Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse')
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java188
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/BooleanEditionFactory.java85
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IAtomicOperationExecutor.java93
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IntegerEditionFactory.java80
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/RealEditionFactory.java77
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/ReferenceValueFactory.java96
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/StringEditionFactory.java162
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/UnlimitedNaturalEditionFactory.java88
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CLabelObservableValue.java121
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ComboObservableValue.java135
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextMultiReferenceDialogObservableValue.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextObservableValue.java121
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextReferenceDialogObservableValue.java68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/GrayedCheckboxObservableValue.java114
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ReferenceDialogObservableValue.java63
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextObservableValue.java152
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextReferenceDialogObservableValue.java91
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/TextObservableValue.java118
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractEditor.java509
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractListEditor.java155
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractReferenceDialog.java182
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractValueEditor.java299
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCheckbox.java144
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCombo.java144
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanRadio.java144
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanToggle.java179
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BrowseFileEditor.java408
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleIntegerEditor.java73
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleReferenceEditor.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleStringEditor.java73
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleValueEditor.java288
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextMultipleReferenceEditor.java128
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextReferenceDialog.java82
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextStringEditor.java175
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/DoubleEditor.java120
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EditorParentComposite.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumCombo.java53
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumRadio.java261
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/FloatEditor.java69
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ICommitListener.java35
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelectionListener.java18
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelector.java84
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IReferenceValueEditor.java83
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ITreeSelectorDialog.java89
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialog.java220
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialogWithLocation.java72
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerEditor.java146
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerMask.java216
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerSpinner.java325
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/LongEditor.java53
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleDoubleEditor.java70
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleIntegerEditor.java75
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleReferenceEditor.java115
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringEditor.java181
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringFileEditor.java228
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java725
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionDialog.java315
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionWithCheckBoxDialog.java158
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialog.java777
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialogWithCheckBox.java180
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultiplicityDialog.java626
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceCombo.java330
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceDialog.java616
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionEditor.java543
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionMenu.java291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringCombo.java241
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditor.java480
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditorWithCompletionWrapper.java200
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringFileSelector.java244
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringLabel.java161
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringMask.java222
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java744
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextStringEditor.java573
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TreeSelectorDialog.java270
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TwoInputDialog.java134
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/UnlimitedNaturalEditor.java125
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java141
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties57
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractFilteredContentProvider.java106
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractRestrictedContentProvider.java111
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractStaticContentProvider.java39
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java182
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CollectionContentProvider.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ComboLabelProvider.java43
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompositeContentProvider.java103
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompoundFilteredRestrictedContentProvider.java149
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingLabelProvider.java125
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingStyledLabelProvider.java61
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EmptyContentProvider.java45
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EncapsulatedContentProvider.java305
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FileExtensions.java48
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FilteredContentProvider.java107
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FlattenableRestrictedFilteredContentProvider.java203
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/HierarchicToFlatContentProvider.java87
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IAdaptableContentProvider.java42
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ICompositeContentProvider.java22
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IFlattenableContentProvider.java27
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IGraphicalContentProvider.java41
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IHierarchicContentProvider.java38
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IInheritedElementContentProvider.java39
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IRestrictedContentProvider.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IStaticContentProvider.java33
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/MapLabelProvider.java25
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/PatternViewerFilter.java83
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/SemanticWorkspaceContentProvider.java151
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/StaticContentProvider.java75
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeCollectionContentProvider.java73
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeToFlatContentProvider.java112
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnchangedObject.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnsetObject.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkbenchFilteredLabelProvider.java70
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkspaceContentProvider.java135
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WrappedLabelProvider.java121
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/BooleanSelector.java49
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/IntegerSelector.java44
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/NullSelector.java61
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/RealSelector.java44
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/ReferenceSelector.java436
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StandardSelector.java138
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StringSelector.java155
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/AbstractTreeBrowseStrategy.java34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/IStrategyBasedContentProvider.java22
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/ProviderBasedBrowseStrategy.java179
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/StrategyBasedContentProvider.java100
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/TreeBrowseStrategy.java39
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/WorkspaceRevealStrategy.java77
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/DoNothingCompletionProposal.java146
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/FileUtil.java112
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/INameResolutionHelper.java50
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IPapyrusConverter.java164
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IRevealSemanticElement.java34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetNameResolutionHelper.java30
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetPapyrusConverter.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageConstants.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageDescriptorManager.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/MultiplicityConstants.java45
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/NavigationTarget.java47
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/PopupButtonMenu.java88
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealResultCommand.java220
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealSemanticElementWrapper.java45
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ValueUtils.java34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/AbstractValidator.java48
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanInputValidator.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanValidator.java51
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/InputValidatorWrapper.java45
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerInputValidator.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerValidator.java55
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealInputValidator.java26
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealValidator.java52
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalInputValidator.java26
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalValidator.java100
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueEditAndSelectionWidget.java168
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWidget.java822
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWithCheckboxWidget.java168
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/wizard/pages/MultipleValueEditAndSelectionWizardPage.java263
155 files changed, 23082 insertions, 0 deletions
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java
new file mode 100644
index 00000000000..fe1993a263b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.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.infra.widgets;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.papyrus.infra.widgets.util.ImageDescriptorManager;
+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.infra.widgets"; //$NON-NLS-1$
+
+ /**
+ * The shared instance
+ */
+ private static Activator plugin;
+
+ /**
+ * The logger for this plugin
+ */
+ public static LogHelper log;
+
+ /**
+ * The logger for this plugin
+ */
+ public ImageDescriptorManager imageDescriptorManager;
+
+ /**
+ * 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);
+ imageDescriptorManager = new ImageDescriptorManager();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ log = null;
+ imageDescriptorManager.reset();
+ imageDescriptorManager = 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;
+ }
+
+ public Image getImage(ImageDescriptor descriptor) {
+ final ImageRegistry registry = getImageRegistry();
+ if (imageDescriptorManager == null || registry == null) {
+ return null; // should never happen => is set to null when activator is not started
+ }
+ String key = imageDescriptorManager.getKey(descriptor);
+ Image image = registry.get(key);
+ if (image == null) {
+ registry.put(key, descriptor);
+ image = registry.get(key);
+ }
+ return image;
+ }
+
+ /**
+ * Returns the image from the given image location
+ *
+ * @param pluginId
+ * The plugin in which the image is located
+ * @param path
+ * The path to the image from the plugin
+ * @return
+ * The Image Descriptor at the given location, or null if it
+ * couldn't be found
+ */
+ public ImageDescriptor getImageDescriptor(String pluginId, String path) {
+ final ImageRegistry registry = getImageRegistry();
+ String key = pluginId + "/" + path; //$NON-NLS-1$
+ ImageDescriptor descriptor = registry.getDescriptor(key);
+ if (descriptor == null) {
+ registry.put(key, AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, path));
+ descriptor = registry.getDescriptor(key);
+ }
+ return descriptor;
+ }
+
+ /**
+ * Returns the image descriptor at the given path from this plugin
+ *
+ * @param path
+ * the path of the image to be displayed
+ * @return The ImageDescriptor at the given location, or null if it couldn't be found
+ */
+ public ImageDescriptor getImageDescriptor(String path) {
+ return getImageDescriptor(PLUGIN_ID, path);
+ }
+
+ /**
+ * 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/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/BooleanEditionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/BooleanEditionFactory.java
new file mode 100644
index 00000000000..1ac8e433d49
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/BooleanEditionFactory.java
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.papyrus.infra.widgets.validator.BooleanInputValidator;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * The factory for the boolean
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class BooleanEditionFactory extends StringEditionFactory {
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public BooleanEditionFactory() {
+ this(new BooleanInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param validator
+ * The InputValidator used to check the entered String
+ */
+ public BooleanEditionFactory(IInputValidator validator) {
+ super(validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a Boolean
+ * @param label
+ * The Label used to describe the kind of value being edited
+ * @param validator
+ * The validator used to check the Booleans being edited
+ */
+ public BooleanEditionFactory(String title, String label, IInputValidator validator) {
+ super(title, label, validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a Boolean
+ * @param label
+ * The Label used to describe the kind of value being edited
+ */
+ public BooleanEditionFactory(String title, String label) {
+ super(title, label, new BooleanInputValidator());
+ }
+
+ @Override
+ public Object createObject(Control widget, Object context) {
+ String txt = super.createObject(widget, context).toString();
+ if (txt != null) {
+ return Boolean.parseBoolean(txt);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IAtomicOperationExecutor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IAtomicOperationExecutor.java
new file mode 100644
index 00000000000..304150f7449
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IAtomicOperationExecutor.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import java.util.concurrent.Callable;
+
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.papyrus.infra.widgets.Activator;
+
+
+/**
+ * An interface that ensures execution of model changes as an atomic unit that is potentially undoable and redoable, such as on a "command stack"
+ * (whatever form it may take).
+ */
+public interface IAtomicOperationExecutor {
+
+ IAtomicOperationExecutor DEFAULT = new Default();
+
+ /**
+ * Execute a runnable (an operation returning no result).
+ *
+ * @param operation
+ * the operation to execute
+ * @param label
+ * an optional label to associate with the operation for presentation in, for example, the Edit menu's Undo/Redo operations
+ */
+ void execute(Runnable operation, String label);
+
+ /**
+ * Execute a callable (an operation returning a result).
+ *
+ * @param operation
+ * the operation to execute
+ * @param label
+ * an optional label to associate with the operation for presentation in, for example, the Edit menu's Undo/Redo operations
+ * @return the {@code operation}'s result
+ */
+ <V> V execute(Callable<V> operation, String label);
+
+ //
+ // Nested types
+ //
+
+ class Default implements IAtomicOperationExecutor {
+
+ @Override
+ public void execute(final Runnable operation, String label) {
+ try {
+ operation.run();
+ } catch (OperationCanceledException e) {
+ // We cannot really implement cancel because there is not command/transaction to roll back
+ }
+ }
+
+ @Override
+ public <V> V execute(final Callable<V> operation, String label) {
+ class CallableWrapper implements Runnable {
+
+ V result;
+
+ @Override
+ public void run() {
+ try {
+ result = operation.call();
+ } catch (OperationCanceledException e) {
+ // Don't trap this one
+ throw e;
+ } catch (Exception e) {
+ Activator.log.error("Callable operation failed.", e); //$NON-NLS-1$
+ throw new OperationCanceledException(); // roll back
+ }
+ }
+ }
+
+ CallableWrapper wrapper = new CallableWrapper();
+
+ execute(wrapper, label);
+
+ return wrapper.result;
+ }
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IntegerEditionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IntegerEditionFactory.java
new file mode 100644
index 00000000000..ea94a8e7cf9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/IntegerEditionFactory.java
@@ -0,0 +1,80 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.papyrus.infra.widgets.validator.IntegerInputValidator;
+import org.eclipse.swt.widgets.Control;
+
+
+public class IntegerEditionFactory extends StringEditionFactory {
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public IntegerEditionFactory() {
+ this(new IntegerInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param validator
+ * The InputValidator used to check the entered Integer
+ */
+ public IntegerEditionFactory(IInputValidator validator) {
+ super(validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing an Integer
+ * @param label
+ * The Label used to describe the kind of value being edited
+ * @param validator
+ * The validator used to check the Integers being edited
+ */
+
+ public IntegerEditionFactory(String title, String label, IInputValidator validator) {
+ super(title, label, validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a Integer
+ * @param label
+ * The Label used to describe the kind of value being edited
+ */
+ public IntegerEditionFactory(String title, String label) {
+ this(title, label, new IntegerInputValidator());
+ }
+
+ @Override
+ public Object createObject(Control widget, Object context) {
+ String txt = super.createObject(widget, context).toString();
+ if (txt != null) {
+ return Integer.parseInt(txt);
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/RealEditionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/RealEditionFactory.java
new file mode 100644
index 00000000000..a1360c0a079
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/RealEditionFactory.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.papyrus.infra.widgets.validator.RealInputValidator;
+
+/**
+ * The factory for real
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class RealEditionFactory extends StringEditionFactory {
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public RealEditionFactory() {
+ this(new RealInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a real
+ * @param label
+ * The Label used to describe the kind of value being edited
+ */
+ public RealEditionFactory(String title, String label) {
+ this(title, label, new RealInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param validator
+ * The InputValidator used to check the entered Real
+ */
+ public RealEditionFactory(IInputValidator validator) {
+ super(validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a Real
+ * @param label
+ * The Label used to describe the kind of value being edited
+ * @param validator
+ * The validator used to check the Reals being edited
+ */
+ public RealEditionFactory(String title, String label, IInputValidator validator) {
+ super(title, label, validator);
+ }
+
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/ReferenceValueFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/ReferenceValueFactory.java
new file mode 100644
index 00000000000..b58b0af45f9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/ReferenceValueFactory.java
@@ -0,0 +1,96 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import java.util.Collection;
+
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A Factory for instantiating new Objects (Typically, from an Editor, although it could be
+ * used elsewhere)
+ * The caller of this Factory is responsible for storing the objects. However, in some cases,
+ * the objects must be created in a specific parent, which is different than the Source object
+ * Typically, it may happen that we need to reference an object that hasn't been yet created. If this
+ * reference is the container of the object, it isn't a problem, but sometime it is not it's container.
+ * In this case, it's the responsibility of the Factory to create the object in its container. The
+ * caller will then refer it from wherever it needs it.
+ *
+ * @author Camille Letavernier
+ */
+public interface ReferenceValueFactory {
+
+ /**
+ * Indicates if this factory can create new instances
+ *
+ * @return
+ * True if the factory can create a new object
+ */
+ public boolean canCreateObject();
+
+ /**
+ * Creates a new Object
+ * The widget Control can be used to display a dialog if additional
+ * information is needed to create the object (e.g. the users needs
+ * to input a name)
+ * This method is used to create objects that <b>won't necessarily</b> be attached
+ * to a parent (For example, the user can start creating an object, then cancel the operation :
+ * the Java Object will therefore be created, but won't be attached to anything, and then will
+ * be garbage collected). That's why this method should *not* attach the object to the given source.
+ *
+ * @param widget
+ * The widget calling this factory. It can be used for example to retrieve
+ * the Display for opening a Dialog
+ * @param context
+ * The object being edited, in which context the new object is to be created and which will as a result have a reference to the new object.
+ * If there is no context object (creation of a free-floating object) or it cannot be determined, this may be {@code null}
+ * @return
+ * The newly created object, or null if no object has been created
+ */
+ public Object createObject(Control widget, Object context);
+
+ /**
+ * The objects have been validated (For example, the user pressed "Ok")
+ * This method should attach the objects where they belong.
+ * Note however that the newly created objects will automatically be attached
+ * to their source. If the source is their container, then this method should probably
+ * not do anything. However, if the source is a simple reference, this method should
+ * attach these objects to their container.
+ *
+ * @param objectsToValidate
+ * The newly created objects that need to be validated
+ * @return
+ * The validated objects
+ */
+ public Collection<Object> validateObjects(Collection<Object> objectsToValidate);
+
+ /**
+ * Indicates if this factory can edit an object
+ *
+ * @return
+ * True if the Factory can edit an object
+ */
+ public boolean canEdit();
+
+ /**
+ * Starts the edition of the given object
+ *
+ * @param widget
+ * The widget calling the factory. May be used for example to retrieve the shell for opening a Dialog.
+ * @param object
+ * The object to edit
+ * @return the edited object, or null if the object has been edited "in place"
+ */
+ public Object edit(Control widget, Object object);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/StringEditionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/StringEditionFactory.java
new file mode 100644
index 00000000000..0b845e24275
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/StringEditionFactory.java
@@ -0,0 +1,162 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import java.util.Collection;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.widgets.editors.InputDialog;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A ValueFactory for editing Strings
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class StringEditionFactory implements ReferenceValueFactory {
+
+ private String title = Messages.StringEditionFactory_EnterANewValue;
+
+ private String label = Messages.StringEditionFactory_EnterANewValue;
+
+ private IInputValidator validator;
+
+ private IStaticContentProvider contentProvider;
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public StringEditionFactory() {
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a String
+ * @param label
+ * The Label used to describe the kind of value being edited
+ */
+ public StringEditionFactory(String title, String label) {
+ this.title = title;
+ this.label = label;
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param validator
+ * The InputValidator used to check the entered String
+ */
+ public StringEditionFactory(IInputValidator validator) {
+ this.validator = validator;
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a String
+ * @param label
+ * The Label used to describe the kind of value being edited
+ * @param validator
+ * The validator used to check the Strings being edited
+ */
+ public StringEditionFactory(String title, String label, IInputValidator validator) {
+ this.title = title;
+ this.label = label;
+ this.validator = validator;
+ }
+
+ @Override
+ public boolean canCreateObject() {
+ return true;
+ }
+
+ @Override
+ public Object createObject(Control widget, Object context) {
+ InputDialog dialog = new InputDialog(widget.getShell(), title, label, "", validator); //$NON-NLS-1$
+ if (contentProvider != null) {
+ dialog.setContentProvider(contentProvider);
+ }
+
+ int result = dialog.open();
+ if (result == Window.OK) {
+ String newValue = dialog.getText();
+ return newValue;
+ }
+
+ return null;
+ }
+
+ @Override
+ public Collection<Object> validateObjects(Collection<Object> objectsToValidate) {
+ return objectsToValidate;
+ }
+
+ @Override
+ public boolean canEdit() {
+ return true;
+ }
+
+ @Override
+ public Object edit(Control widget, Object object) {
+ if (!(object instanceof String)) {
+ return object;
+ }
+
+ InputDialog dialog = new InputDialog(widget.getShell(), title, label, (String) object, validator);
+ if (contentProvider != null) {
+ dialog.setContentProvider(contentProvider);
+ }
+
+ int result = dialog.open();
+ if (result == Window.OK) {
+ String newValue = dialog.getText();
+ return newValue;
+ }
+
+ return object;
+ }
+
+ /**
+ * Sets the Validator for this factory
+ *
+ * @param validator
+ * The InputValidator to be used to check the input String
+ */
+ public void setValidator(IInputValidator validator) {
+ this.validator = validator;
+ }
+
+ /**
+ * Sets the content provider for this edition factory. The ContentProvider is used
+ * to suggest values to the user.
+ *
+ * @param provider
+ * The provider which will make suggestions to the user
+ */
+ public void setContentProvider(IStaticContentProvider provider) {
+ this.contentProvider = provider;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/UnlimitedNaturalEditionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/UnlimitedNaturalEditionFactory.java
new file mode 100644
index 00000000000..d9265e67e75
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/creation/UnlimitedNaturalEditionFactory.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.creation;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.papyrus.infra.widgets.validator.UnlimitedNaturalInputValidator;
+import org.eclipse.papyrus.infra.widgets.validator.UnlimitedNaturalValidator;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ *
+ * The factory for UnlimitedNatural
+ *
+ */
+public class UnlimitedNaturalEditionFactory extends StringEditionFactory {
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public UnlimitedNaturalEditionFactory() {
+ this(new UnlimitedNaturalInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing an UnlimitedNatural
+ * @param label
+ * The Label used to describe the kind of value being edited
+ */
+ public UnlimitedNaturalEditionFactory(String title, String label) {
+ super(title, label, new UnlimitedNaturalInputValidator());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param validator
+ * The InputValidator used to check the entered UnlimitedNatural
+ */
+ public UnlimitedNaturalEditionFactory(IInputValidator validator) {
+ super(validator);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param title
+ * The title of the dialog opened by this factory when editing a UnlimitedNatural
+ * @param label
+ * The Label used to describe the kind of value being edited
+ * @param validator
+ * The validator used to check the UnlimitedNaturals being edited
+ */
+ public UnlimitedNaturalEditionFactory(String title, String label, IInputValidator validator) {
+ super(title, label, validator);
+ }
+
+ @Override
+ public Object createObject(Control widget, Object context) {
+ String txt = super.createObject(widget, context).toString();
+ if (UnlimitedNaturalValidator.INFINITE_STAR.equals(txt)) {
+ txt = UnlimitedNaturalValidator.INFINITE_MINUS_ONE;
+ }
+ if (txt != null) {
+ return Integer.parseInt(txt);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CLabelObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CLabelObservableValue.java
new file mode 100644
index 00000000000..c653eedd906
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CLabelObservableValue.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * 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.infra.widgets.databinding;
+
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.swt.custom.CLabel;
+
+/**
+ * An IObservableValue to edit a CLabel (Text + Image), based on a LabelProvider
+ * It supports AggregatedObservable
+ *
+ * @author Camille Letavernier
+ */
+public class CLabelObservableValue extends AbstractObservableValue {
+
+ /**
+ * The observed CLabel
+ */
+ protected CLabel label;
+
+ /**
+ * The current value
+ */
+ protected Object currentValue;
+
+ /**
+ * The LabelProvider used to define the CLabel's text and image,
+ * based on the current value
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * If the CLabel may represent more than one value,
+ * use an AggregatedObservable
+ *
+ * May be null
+ */
+ protected AggregatedObservable aggregated;
+
+ /**
+ * Constructor
+ *
+ * @param label
+ * The observed CLabel
+ * @param modelObservable
+ * The Model IObservable
+ */
+ public CLabelObservableValue(CLabel label, IObservableValue modelObservable) {
+ this(label, modelObservable, null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param label
+ * The observed CLabel
+ * @param modelObservable
+ * The Model IObservable
+ * @param labelProvider
+ * The LabelProvider used to define the CLabel's text/image from the current value
+ */
+ public CLabelObservableValue(CLabel label, IObservableValue modelObservable, ILabelProvider labelProvider) {
+ this.label = label;
+ setLabelProvider(labelProvider);
+ if (modelObservable instanceof AggregatedObservable) {
+ this.aggregated = (AggregatedObservable) modelObservable;
+ }
+ }
+
+ /**
+ * @param labelProvider
+ * The LabelProvider used to define the CLabel's text and image,
+ * based on the current value
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ if (labelProvider != null) {
+ this.labelProvider = labelProvider;
+ } else {
+ this.labelProvider = new LabelProvider();
+ }
+ }
+
+ @Override
+ public Object getValueType() {
+ return Object.class;
+ }
+
+ @Override
+ protected Object doGetValue() {
+ return currentValue;
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ this.currentValue = value;
+ if (aggregated != null && aggregated.hasDifferentValues()) {
+ label.setText(Messages.ReferenceDialogObservable_Unchanged);
+ label.setImage(null);
+ } else if (currentValue == null) {
+ label.setText(Messages.ReferenceDialog_Unset);
+ label.setImage(null);
+ } else {
+ label.setText(labelProvider.getText(value));
+ label.setImage(labelProvider.getImage(value));
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ComboObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ComboObservableValue.java
new file mode 100644
index 00000000000..4b6821538bd
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ComboObservableValue.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * 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.infra.widgets.databinding;
+
+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.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.providers.ComboLabelProvider;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.papyrus.infra.widgets.providers.UnsetObject;
+
+/**
+ * An ObservableValue for a ComboViewer, with support for AggregatedObservable
+ *
+ * @author Camille Letavernier
+ */
+public class ComboObservableValue extends AbstractObservableValue implements ISelectionChangedListener {
+
+ /**
+ * The Observed ComboViewer
+ */
+ protected ComboViewer viewer;
+
+ /**
+ * The current value
+ */
+ protected Object currentValue;
+
+ /**
+ * If the Combo may represent more than one value,
+ * use an AggregatedObservable
+ *
+ * May be null
+ */
+ protected AggregatedObservable modelProperty;
+
+ /**
+ *
+ * @param viewer
+ * The observed ComboViewer
+ * @param modelProperty
+ * The Model IObservable
+ */
+ public ComboObservableValue(ComboViewer viewer, IObservableValue modelProperty) {
+ this.viewer = viewer;
+ viewer.setLabelProvider(new ComboLabelProvider(viewer.getLabelProvider()));
+ if (modelProperty instanceof AggregatedObservable) {
+ this.modelProperty = (AggregatedObservable) modelProperty;
+ }
+ viewer.addSelectionChangedListener(this);
+ }
+
+ @Override
+ public Object getValueType() {
+ return Object.class;
+ }
+
+ @Override
+ protected Object doGetValue() {
+ ISelection selection = viewer.getSelection();
+ if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ Object firstElement = structuredSelection.getFirstElement();
+ if (firstElement == UnsetObject.instance) {
+ return null;
+ }
+ if (firstElement == UnchangedObject.instance) {
+ return null;
+ }
+ return firstElement;
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ currentValue = value;
+
+ if (modelProperty != null && modelProperty.hasDifferentValues()) {
+ viewer.setSelection(new StructuredSelection(UnchangedObject.instance));
+ } else if (value == null) {
+ viewer.setSelection(new StructuredSelection(UnsetObject.instance));
+ } else {
+ viewer.setSelection(new StructuredSelection(value));
+ }
+ }
+
+ @Override
+ public synchronized void dispose() {
+ viewer.removeSelectionChangedListener(this);
+ super.dispose();
+ }
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (((IStructuredSelection) event.getSelection()).getFirstElement() != UnchangedObject.instance) {
+
+ final Object oldValue = currentValue;
+ final Object newValue = doGetValue();
+ currentValue = newValue;
+
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return newValue;
+ }
+
+ });
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextMultiReferenceDialogObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextMultiReferenceDialogObservableValue.java
new file mode 100644
index 00000000000..33e481ba136
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextMultiReferenceDialogObservableValue.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+import java.util.Collection;
+
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author Vincent Lorenzo
+ *
+ */
+public class CompletionStyledTextMultiReferenceDialogObservableValue extends CompletionStyledTextObservableValue {
+
+ /**
+ * the styled text with completion reference dialog
+ */
+ private Control referenceDialog;
+
+ /**
+ * the IObservable list
+ */
+ private IObservableList list;
+
+ /**
+ * @param dialog
+ * The observed StyledTextReferenceDialog
+ * @param styledText
+ * The observed StyledText
+ * @param modelObservable
+ * The Model IObservable
+ * @param eventType
+ * The eventType to listen to. When the event is fired by the Text
+ * widget, this IObservableValue will fire a ChangeEvent
+ */
+ public CompletionStyledTextMultiReferenceDialogObservableValue(Control dialog, StyledText styledText, IObservableList modelObservable, int eventType) {
+ super(styledText, null, eventType);
+ this.referenceDialog = dialog;
+ list = modelObservable;
+ }
+
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue#doSetValue(java.lang.Object)
+ *
+ * @param value
+ */
+ @Override
+ protected void doSetValue(Object value) {
+ super.doSetValue(value);
+ referenceDialog.update();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.databinding.CompletionStyledTextObservableValue#doGetValue()
+ *
+ * @return
+ */
+ @Override
+ protected Object doGetValue() {
+ Object newValues = super.doGetValue();
+ if (newValues instanceof Collection<?>) {
+ if (!list.equals(newValues)) {
+ list.clear();
+ list.addAll((Collection<?>) newValues);
+ }
+ }else if(newValues==null){
+ list.clear();
+ }
+ return newValues;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextObservableValue.java
new file mode 100644
index 00000000000..7a6eb78f706
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextObservableValue.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
+import org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Event;
+
+public class CompletionStyledTextObservableValue extends StyledTextObservableValue implements ISetPapyrusConverter {
+
+ /**
+ * The name resolution helper shared with the widget
+ */
+ protected IPapyrusConverter parser;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param text
+ * @param modelProperty
+ * @param eventType
+ */
+ public CompletionStyledTextObservableValue(StyledText text, IObservableValue modelProperty, int eventType) {
+ super(text, modelProperty, eventType);
+
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue#doSetValue(java.lang.Object)
+ *
+ * @param value
+ */
+ @Override
+ protected void doSetValue(Object value) {
+ String editValue = parser.canonicalToEditValue(value, 0);
+ if (editValue instanceof String) {
+ super.doSetValue(editValue);
+ } else {
+ super.doSetValue(value);
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue#doGetValue()
+ *
+ * @return²
+ */
+ @Override
+ protected Object doGetValue() {
+ Object newValue = super.doGetValue();
+ if (newValue instanceof String) {
+ if (IPapyrusConverter.UNDEFINED_VALUE.equals(newValue)) {
+ return null;
+ }
+ Object result = this.parser.editToCanonicalValue((String) newValue, 0);
+ return result;
+ }
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter#setPapyrusConverter(org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter)
+ *
+ * @param parser
+ */
+ @Override
+ public void setPapyrusConverter(IPapyrusConverter parser) {
+ this.parser = parser;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ @Override
+ public void handleEvent(final Event event) {
+
+ final Object oldValue = currentValue;
+ final Object newValue = getValue();
+ // if (newValue == null) {
+ // return;
+ // }
+ currentValue = newValue;
+
+ if ((eventType & event.type) != 0) {
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return newValue;
+ }
+
+ });
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextReferenceDialogObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextReferenceDialogObservableValue.java
new file mode 100644
index 00000000000..ef22a7ba233
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/CompletionStyledTextReferenceDialogObservableValue.java
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.infra.widgets.editors.CompletionStyledTextReferenceDialog;
+import org.eclipse.swt.custom.StyledText;
+
+/**
+ * @author VL222926
+ *
+ */
+public class CompletionStyledTextReferenceDialogObservableValue extends CompletionStyledTextObservableValue {
+
+ /**
+ * the styled text with completion reference dialog
+ */
+ private CompletionStyledTextReferenceDialog referenceDialog;
+
+ /**
+ * @param dialog
+ * The observed StyledTextReferenceDialog
+ * @param styledText
+ * The observed StyledText
+ * @param modelObservable
+ * The Model IObservable
+ * @param eventType
+ * The eventType to listen to. When the event is fired by the Text
+ * widget, this IObservableValue will fire a ChangeEvent
+ */
+ public CompletionStyledTextReferenceDialogObservableValue(CompletionStyledTextReferenceDialog dialog, StyledText styledText, IObservableValue modelObservable, int eventType) {
+ super(styledText, modelObservable, eventType);
+ this.referenceDialog = dialog;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue#doSetValue(java.lang.Object)
+ *
+ * @param value
+ */
+ @Override
+ protected void doSetValue(Object value) {
+ super.doSetValue(value);
+ referenceDialog.update();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.databinding.CompletionStyledTextObservableValue#doGetValue()
+ *
+ * @return
+ */
+ @Override
+ protected Object doGetValue() {
+ return super.doGetValue();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/GrayedCheckboxObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/GrayedCheckboxObservableValue.java
new file mode 100644
index 00000000000..2e40f91e770
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/GrayedCheckboxObservableValue.java
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * 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.infra.widgets.databinding;
+
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
+import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+
+/**
+ * An ObservableValue for {@link Button}s with the {@link SWT.CHECK} style
+ * Allows the checkbox to take four states ; one for each possible combination
+ * of {@link Button#getSelection()} and {@link Button#getGrayed()}
+ *
+ * @author Camille Letavernier
+ */
+public class GrayedCheckboxObservableValue extends AbstractObservableValue implements SelectionListener {
+
+ private Button checkbox;
+
+ private Boolean currentValue;
+
+ private AggregatedObservable aggregated;
+
+ /**
+ * Constructor
+ *
+ * @param checkbox
+ * The observed checkbox
+ * @param aggregated
+ * The Observable aggregating the various observable booleans
+ */
+ public GrayedCheckboxObservableValue(Button checkbox, AggregatedObservable aggregated) {
+ this.checkbox = checkbox;
+ this.checkbox.addSelectionListener(this);
+ this.aggregated = aggregated;
+ }
+
+ @Override
+ public Object getValueType() {
+ return Object.class; // Can be either Boolean or BooleanWithDefaultState
+ }
+
+ @Override
+ protected Boolean doGetValue() {
+ return checkbox.getSelection();
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ if (aggregated.hasDifferentValues()) {
+ checkbox.setSelection(true);
+ checkbox.setGrayed(true);
+ return;
+ } else {
+ checkbox.setGrayed(false);
+ }
+
+ if (value instanceof Boolean) {
+ Boolean booleanValue = (Boolean) value;
+ checkbox.setSelection(booleanValue);
+
+ this.currentValue = booleanValue;
+ } else if (value == null) {
+ checkbox.setSelection(false);
+ }
+ }
+
+ @Override
+ public synchronized void dispose() {
+ checkbox.removeSelectionListener(this);
+ super.dispose();
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final Boolean oldValue = currentValue;
+ final Boolean newValue = checkbox.getSelection();
+
+ currentValue = newValue;
+ checkbox.setGrayed(false);
+
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return newValue;
+ }
+ });
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ReferenceDialogObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ReferenceDialogObservableValue.java
new file mode 100644
index 00000000000..21c70b3f2d3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/ReferenceDialogObservableValue.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * 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.infra.widgets.databinding;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.editors.ReferenceDialog;
+import org.eclipse.swt.custom.CLabel;
+
+
+/**
+ * An ObservableValue for ReferenceDialog widget (Which displays
+ * the current value with a CLabel)
+ *
+ * @author Camille Letavernier
+ */
+public class ReferenceDialogObservableValue extends CLabelObservableValue {
+
+ private ReferenceDialog referenceDialog;
+
+ /**
+ * @param dialog
+ * The observed ReferenceDialog
+ * @param label
+ * The observed CLabel (Should correspond to dialog#currentValueLabel)
+ * @param modelObservable
+ * The Model IObservable
+ */
+ public ReferenceDialogObservableValue(ReferenceDialog dialog, CLabel label, IObservableValue modelObservable) {
+ this(dialog, label, modelObservable, null);
+ }
+
+ /**
+ * @param dialog
+ * The observed ReferenceDialog
+ * @param label
+ * The observed CLabel (Should correspond to dialog#currentValueLabel)
+ * @param modelObservable
+ * The Model IObservable
+ * @param labelProvider
+ * The LabelProvider used to define the CLabel's text/image from the current value
+ */
+ public ReferenceDialogObservableValue(ReferenceDialog dialog, CLabel label, IObservableValue modelObservable, ILabelProvider labelProvider) {
+ super(label, modelObservable, labelProvider);
+ this.referenceDialog = dialog;
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ super.doSetValue(value);
+ referenceDialog.update();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextObservableValue.java
new file mode 100644
index 00000000000..19ab83c7351
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextObservableValue.java
@@ -0,0 +1,152 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+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.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * An ObservableValue for StyledText field, with support for AggregatedObservable
+ *
+ * @author Vincent Lorenzo
+ */
+public class StyledTextObservableValue extends AbstractObservableValue implements Listener {
+
+ /**
+ * The styled text.
+ */
+ protected StyledText text;
+
+ /**
+ * The event type used by the styled text.
+ */
+ protected int eventType;
+
+ /**
+ * The current value.
+ */
+ protected Object currentValue;
+
+ /**
+ * If the Text field may represent more than one value,
+ * use an AggregatedObservable.
+ *
+ * May be null.
+ */
+ protected AggregatedObservable modelProperty;
+
+ /**
+ * Constructor
+ *
+ * @param text
+ * The Text field to observe
+ * @param modelProperty
+ * The model IObservableValue
+ * @param eventType
+ * The eventType to listen to. When the event is fired by the Text
+ * widget, this IObservableValue will fire a ChangeEvent
+ */
+ public StyledTextObservableValue(final StyledText text, final IObservableValue modelProperty, final int eventType) {
+ this.text = text;
+ this.eventType = eventType;
+ if (modelProperty instanceof AggregatedObservable) {
+ this.modelProperty = (AggregatedObservable) modelProperty;
+ }
+ this.text.addListener(eventType, this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType()
+ */
+ @Override
+ public Object getValueType() {
+ return String.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doGetValue()
+ */
+ @Override
+ protected Object doGetValue() {
+ if (UnchangedObject.instance.toString().equals(text.getText())) {
+ return null;
+ } else {
+ return text.getText();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doSetValue(java.lang.Object)
+ */
+ @Override
+ protected void doSetValue(final Object value) {
+ if (modelProperty != null && modelProperty.hasDifferentValues()) {
+ this.text.setText(UnchangedObject.instance.toString());
+ this.currentValue = UnchangedObject.instance;
+ } else {
+ if (value instanceof String) {
+ this.text.setText((String) value);
+ this.currentValue = value;
+ } else if (value == null) {
+ this.text.setText(""); //$NON-NLS-1$
+ this.currentValue = null;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ @Override
+ public void handleEvent(final Event event) {
+
+ final Object oldValue = currentValue;
+ final Object newValue = getValue();
+ if (newValue == null) {
+ return;
+ }
+ currentValue = newValue;
+
+ if ((eventType & event.type) != 0) {
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return newValue;
+ }
+
+ });
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextReferenceDialogObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextReferenceDialogObservableValue.java
new file mode 100644
index 00000000000..eb77f7e30d1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/StyledTextReferenceDialogObservableValue.java
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.swt.custom.StyledText;
+
+/**
+ * An ObservableValue for ReferenceDialog widget (Which displays
+ * the current value with a CLabel)
+ */
+public class StyledTextReferenceDialogObservableValue extends StyledTextObservableValue {
+
+ /**
+ * The value editor.
+ */
+ private AbstractValueEditor referenceDialog;
+
+ /**
+ * The label provider used to get the text value.
+ */
+ private ILabelProvider labelProvider;
+
+ /**
+ * @param dialog
+ * The observed StyledTextReferenceDialog
+ * @param styledText
+ * The observed StyledText
+ * @param modelObservable
+ * The Model IObservable
+ * @param eventType
+ * The eventType to listen to. When the event is fired by the Text
+ * widget, this IObservableValue will fire a ChangeEvent
+ * @param labelProvider
+ * The label provider
+ */
+ public StyledTextReferenceDialogObservableValue(final AbstractValueEditor dialog, final StyledText styledText, final IObservableValue modelObservable, final int eventType, final ILabelProvider labelProvider) {
+ super(styledText, modelObservable, eventType);
+ this.referenceDialog = dialog;
+ this.labelProvider = labelProvider;
+ }
+
+ /**
+ * Set the label provider.
+ *
+ * @param labelProvider
+ * The LabelProvider used to define the CLabel's text and image,
+ * based on the current value
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ if (labelProvider != null) {
+ this.labelProvider = labelProvider;
+ } else {
+ this.labelProvider = new LabelProvider();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue#doSetValue(java.lang.Object)
+ */
+ @Override
+ protected void doSetValue(final Object value) {
+ if (null != modelProperty && modelProperty.hasDifferentValues()) {
+ this.text.setText(UnchangedObject.instance.toString());
+ this.currentValue = UnchangedObject.instance;
+ } else if (value instanceof String) {
+ this.text.setText((String) value);
+ this.currentValue = value;
+ } else {
+ this.text.setText(labelProvider.getText(value));
+ this.currentValue = value;
+ }
+ referenceDialog.update();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/TextObservableValue.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/TextObservableValue.java
new file mode 100644
index 00000000000..823931e278b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/databinding/TextObservableValue.java
@@ -0,0 +1,118 @@
+package org.eclipse.papyrus.infra.widgets.databinding;
+
+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.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * An ObservableValue for Text field, with support for AggregatedObservable
+ *
+ * @author Camille Letavernier
+ */
+public class TextObservableValue extends AbstractObservableValue implements Listener {
+
+ private Text text;
+
+ private int eventType;
+
+ private Object currentValue;
+
+ /**
+ * If the Text field may represent more than one value,
+ * use an AggregatedObservable
+ *
+ * May be null
+ */
+ protected AggregatedObservable modelProperty;
+
+ /**
+ * Constructor
+ *
+ * @param text
+ * The Text field to observe
+ * @param modelProperty
+ * The model IObservableValue
+ * @param eventType
+ * The eventType to listen to. When the event is fired by the Text
+ * widget, this IObservableValue will fire a ChangeEvent
+ */
+ public TextObservableValue(Text text, IObservableValue modelProperty, int eventType) {
+ this.text = text;
+ this.eventType = eventType;
+ if (modelProperty instanceof AggregatedObservable) {
+ this.modelProperty = (AggregatedObservable) modelProperty;
+ }
+ this.text.addListener(eventType, this);
+ }
+
+ @Override
+ public Object getValueType() {
+ return String.class;
+ }
+
+ @Override
+ protected Object doGetValue() {
+ if (this.text == null || this.text.isDisposed()) {
+ return null;
+ }
+
+ if (UnchangedObject.instance.toString().equals(text.getText())) {
+ return null;
+ } else {
+ return text.getText();
+ }
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ if (modelProperty != null && modelProperty.hasDifferentValues()) {
+ this.text.setText(UnchangedObject.instance.toString());
+ this.currentValue = UnchangedObject.instance;
+ } else {
+ if (value instanceof String) {
+ this.text.setText((String) value);
+ this.currentValue = value;
+ } else if (value == null) {
+ this.text.setText(""); //$NON-NLS-1$
+ this.currentValue = null;
+ }
+ }
+ }
+
+ @Override
+ public void handleEvent(Event event) {
+ if (this.text == null || this.text.isDisposed()) {
+ return;
+ }
+
+ final Object oldValue = currentValue;
+ final Object newValue = getValue();
+ if (newValue == null) {
+ return;
+ }
+ currentValue = newValue;
+
+ if ((eventType & event.type) != 0) {
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return newValue;
+ }
+
+ });
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractEditor.java
new file mode 100644
index 00000000000..badc5aa8d51
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractEditor.java
@@ -0,0 +1,509 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 402525
+ * Christian W. Damus (CEA) - bug 435420
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.infra.widgets.creation.IAtomicOperationExecutor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * An Abstract class to represent Editors.
+ * An editor is a Composite, containing a label and one
+ * or more controls. The label may be null.
+ * The controls are specified by the implementations
+ * of this abstract class.
+ *
+ * @author Camille Letavernier
+ */
+// FIXME: The composite widget hides access to the encapsulated widget(s).
+// Thus, it is not possible to add custom listeners on the editors
+// We should forward the listeners to the encapsulated (this.addListener(int, Listener) -> getMainWidget().addListener(int, Listener))
+// Problem: some widgets have more than one "main widget" (e.g. EnumRadio).
+public abstract class AbstractEditor extends Composite implements DisposeListener {
+
+ /**
+ * The label for this editor. May be null.
+ */
+ protected Label label;
+
+ /**
+ * The label value for this editor
+ */
+ protected String labelText;
+
+ /**
+ * The set of elements listening on changes from this editor
+ */
+ protected Set<ICommitListener> commitListeners = new LinkedHashSet<ICommitListener>();
+
+ /**
+ * The binding between the model object and the widget
+ */
+ protected Binding binding;
+
+ /**
+ * The toolTipText associated to this editor
+ */
+ protected String toolTipText;
+
+ protected DataBindingContext dbc;
+
+ /**
+ * The factory for creating all the editors with a common style
+ */
+ public static final TabbedPropertySheetWidgetFactory factory = new TabbedPropertySheetWidgetFactory();
+
+ static {
+ factory.setBackground(null);
+ factory.setBorderStyle(SWT.BORDER); // This seems to be used only by the FormToolKit factory, we still need to force it for the CLabel or CCombo widgets
+ }
+
+ /**
+ *
+ * Constructor. Constructs an editor without a label
+ *
+ * @param parent
+ * The composite in which this editor should be created
+ */
+ protected AbstractEditor(Composite parent) {
+ this(parent, SWT.NONE, null);
+ }
+
+ /**
+ *
+ * Constructor. Constructs an editor without a label
+ *
+ * @param parent
+ * The composite in which this editor should be created
+ * @param style
+ * The style of this editor's main composite
+ */
+ protected AbstractEditor(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ *
+ * Constructor. Constructs an editor with a label
+ *
+ * @param parent
+ * The composite in which this editor should be created
+ * @param label
+ * The label that will be displayed for this editor, or null
+ * if no label should be displayed
+ */
+ protected AbstractEditor(Composite parent, String label) {
+ this(parent, SWT.NONE, label);
+ }
+
+ /**
+ *
+ * Constructor. Constructs an editor with a label
+ *
+ * @param parent
+ * The composite in which this editor should be created
+ * @param style
+ * The style of this editor's main composite
+ * @param label
+ * The label that will be displayed for this editor, or null
+ * if no label should be displayed
+ */
+ protected AbstractEditor(Composite parent, int style, String label) {
+ super(parent, style);
+ GridLayout layout = new GridLayout(1, false);
+ setLayout(layout);
+ if (label != null) {
+ createLabel(label);
+ }
+ parent.addDisposeListener(this);
+ }
+
+ /**
+ * Creates the label widget with the given text
+ *
+ * @param text
+ * The text to be displayed on the label
+ */
+ protected void createLabel(String text) {
+ label = factory.createLabel(this, text);
+ label.setLayoutData(getLabelLayoutData());
+ if (toolTipText != null) {
+ label.setToolTipText(toolTipText);
+ }
+ ((GridLayout) getLayout()).numColumns++;
+ }
+
+ /**
+ * @return The default layoutData for the label
+ */
+ protected GridData getLabelLayoutData() {
+ GridData data = new GridData();
+ data.widthHint = 120;
+ data.verticalAlignment = SWT.CENTER;
+ return data;
+ }
+
+ /**
+ * This method should be called by subclasses to get the default layoutData
+ * for a control in this editor.
+ *
+ * @return The default layoutData for the main control
+ */
+ protected GridData getDefaultLayoutData() {
+ GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
+ return data;
+ }
+
+ /**
+ * Changes the text label for this editor. This method is available
+ * only when the editor has been constructed with a label.
+ *
+ * @param label
+ * The new text for this editor's label
+ */
+ public void setLabel(String label) {
+ this.labelText = label;
+
+ if (this.label != null) {
+ this.label.setText(label);
+ } else {
+ createLabel(label);
+ this.label.moveAbove(getChildren()[0]);
+ }
+ }
+
+ /**
+ * Show or delete the Label Widget.
+ *
+ * @param displayLabel
+ */
+ public void setDisplayLabel(boolean displayLabel) {
+ if (displayLabel) {
+ setLabel(labelText);
+ } else {
+ if (this.label != null) {
+ this.label.dispose();
+ ((GridLayout) getLayout()).numColumns--;
+ }
+ }
+ }
+
+ /**
+ * Adds a commit listener to this editor. A Commit event is
+ * fired when a modification occurs on this editor.
+ *
+ * @param listener
+ * The commit listener to add to this editor
+ */
+ public void addCommitListener(ICommitListener listener) {
+ commitListeners.add(listener);
+ }
+
+ /**
+ * Removes a commit listener from this editor.
+ *
+ * @param listener
+ * The commit listener to remove from this editor
+ */
+ public void removeCommitListener(ICommitListener listener) {
+ commitListeners.remove(listener);
+ }
+
+ /**
+ * Informs the commit listeners that a modification occured
+ */
+ protected void commit() {
+ for (ICommitListener listener : commitListeners) {
+ listener.commit(this);
+
+ }
+
+
+ }
+
+ /**
+ * Gets the BindingContext associated to the editors
+ *
+ * @return
+ */
+ protected DataBindingContext getBindingContext() {
+ if (dbc == null) {
+ dbc = new DataBindingContext();
+ }
+ return dbc;
+ }
+
+
+ /**
+ * Sets the converters to convert data from Model to Target (Widget),
+ * and from Widget to Model
+ *
+ * @param targetToModel
+ * @param modelToTarget
+ */
+ abstract public void setConverters(IConverter targetToModel, IConverter modelToTarget);
+
+
+ /**
+ * Binds the Widget Observable to the Model observable property,
+ * using the specified converters when available
+ */
+ abstract protected void doBinding();
+
+ /**
+ * @return the type of objects that this widget can edit
+ */
+ public abstract Object getEditableType();
+
+ /**
+ * Marks this editor as being read-only. The value of a read-only
+ * editor cannot be changed by the editor itself.
+ *
+ * @param readOnly
+ */
+ public abstract void setReadOnly(boolean readOnly);
+
+ /**
+ * Tests whether this editor is read-only or not
+ *
+ * @return
+ * True if the editor is read-only
+ */
+ public abstract boolean isReadOnly();
+
+ /**
+ * Indicates that this editor should notify its commit listeners
+ * when the given control looses the Focus
+ *
+ * @param control
+ * The control on which a FocusListener should be added,
+ * to notify the CommitListeners
+ */
+ protected void setCommitOnFocusLost(Control control) {
+ control.addFocusListener(new FocusAdapter() {
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ commit();
+ }
+
+ });
+ }
+
+ /**
+ * Forces the refresh of the widget's value
+ */
+ public void refreshValue() {
+ if (binding != null) {
+ binding.updateModelToTarget();
+ }
+
+ }
+
+ public void refreshModel() {
+ if (binding != null) {
+ binding.updateTargetToModel();
+ }
+
+ }
+
+ /**
+ * Sets the given toolTip to the label
+ *
+ * @param text
+ * The new label's tooltip
+ */
+ protected void setLabelToolTipText(String text) {
+ toolTipText = text;
+ if (label != null && !label.isDisposed()) {
+ label.setToolTipText(text);
+ }
+ }
+
+ /**
+ * Excludes or includes the given control from the layout
+ *
+ * @param control
+ * The control to exclude or include
+ * @param exclude
+ * If true, the control will be excluded ; otherwise, it will be included
+ */
+ protected void setExclusion(Control control, boolean exclude) {
+ if (control.getLayoutData() == null) {
+ GridData data = new GridData();
+ control.setLayoutData(data);
+ }
+
+ GridData data = (GridData) control.getLayoutData();
+
+ if (data.exclude != exclude) {
+ data.exclude = exclude;
+ GridLayout layout = (GridLayout) control.getParent().getLayout();
+ if (exclude) {
+ layout.numColumns--;
+ } else {
+ layout.numColumns++;
+ }
+ }
+ }
+
+
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+
+ public void changeColorField() {
+
+ }
+
+
+ /**
+ * Obtains the most appropriate operation executor for the object being edited.
+ *
+ * @param context
+ * the object being edited
+ * @return the executor to use to run operations (never {@code null})
+ */
+ public IAtomicOperationExecutor getOperationExecutor(Object context) {
+ IAtomicOperationExecutor result;
+ if (context instanceof IAdaptable) {
+ result = ((IAdaptable) context).getAdapter(IAtomicOperationExecutor.class);
+ } else if (context != null) {
+ result = Platform.getAdapterManager().getAdapter(context, IAtomicOperationExecutor.class);
+ } else {
+ // We can't adapt null, of course, so we will have to settle for the default executor
+ result = null;
+ }
+
+ if (result == null) {
+ result = IAtomicOperationExecutor.DEFAULT;
+ }
+
+ return result;
+ }
+
+ /**
+ * A hook to call when a control is accepting a focus that is sensitive to glitches in focus management
+ * on the current SWT platform.
+ *
+ * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=435420">bug 435420</a>
+ */
+ protected final void acceptingFocus() {
+ // On SWT/Cocoa, veto attempts to give focus to any other control for the current event-loop iteration
+ FocusVeto.vetoFocus(this);
+ }
+
+ /**
+ * Queries the model element that I edit.
+ *
+ * @return the contextual model element
+ */
+ protected abstract Object getContextElement();
+
+ //
+ // Nested types
+ //
+
+ /**
+ * A utility that implements a bug in the SWT implementation on Cocoa, in which responder-chain management
+ * while a {@link CCombo} is trying to accept focus in a Property Sheet that currently does not have focus
+ * results in the text contents of some unrelated {@link Text} widget being presented in the {@code CCombo}'s
+ * text field.
+ *
+ * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=435420">bug 435420</a>
+ */
+ static class FocusVeto {
+
+ // Only engage this work-around on the Cocoa implementation of SWT because it actually results in
+ // editable CCombos not getting keyboard focus when initially clicked if the Property Sheet is not
+ // yet active
+ private static final boolean IS_SWT_COCOA = Platform.WS_COCOA.equals(Platform.getWS());
+
+ private final Control focusControl;
+
+ private FocusVeto(Control focusControl) {
+ this.focusControl = focusControl;
+ final Shell shell = focusControl.getShell();
+
+ focusControl.getDisplay().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+
+ removeFocusVeto(shell, FocusVeto.this);
+
+ if (!FocusVeto.this.focusControl.isDisposed() && !FocusVeto.this.focusControl.isFocusControl()) {
+ FocusVeto.this.focusControl.setFocus();
+ }
+ }
+ });
+ }
+
+ Control getFocusControl() {
+ return focusControl;
+ }
+
+ static Control getFocusVetoControl(Control context) {
+ FocusVeto veto = IS_SWT_COCOA ? getFocusVeto(context.getShell()) : null;
+ return (veto == null) ? null : veto.getFocusControl();
+ }
+
+ static void vetoFocus(Control focusControl) {
+ if (IS_SWT_COCOA) {
+ Shell shell = focusControl.getShell();
+ FocusVeto current = getFocusVeto(shell);
+ if (current == null) {
+ setFocusVeto(shell, new FocusVeto(focusControl));
+ }
+ }
+ }
+
+ static FocusVeto getFocusVeto(Shell shell) {
+ return (FocusVeto) shell.getData(FocusVeto.class.getName());
+ }
+
+ static void setFocusVeto(Shell shell, FocusVeto focusVeto) {
+ shell.setData(FocusVeto.class.getName(), focusVeto);
+ }
+
+ static void removeFocusVeto(Shell shell, FocusVeto focusVeto) {
+ if (getFocusVeto(shell) == focusVeto) {
+ shell.setData(FocusVeto.class.getName(), null);
+ }
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractListEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractListEditor.java
new file mode 100644
index 00000000000..652cfc03880
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractListEditor.java
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.UpdateListStrategy;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.observable.IObserving;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An abstract class to represent List Editors.
+ * List editors are based on the Eclipse Databinding Framework
+ * They take {@link IObservableList}s as Input
+ *
+ * @author Camille Letavernier
+ *
+ */
+public abstract class AbstractListEditor extends AbstractEditor {
+
+ /**
+ * The IObservableList associated to the model property
+ */
+ protected IObservableList modelProperty;
+
+ /**
+ * The UpdateStrategy for binding data from widget to model
+ */
+ protected UpdateListStrategy targetToModelStrategy;
+
+ /**
+ * The UpdateStrategy for binding data from model to widget
+ */
+ protected UpdateListStrategy modelToTargetStrategy;
+
+ /**
+ * The IObservableList associated to the widget
+ */
+ protected IObservableList widgetObservable;
+
+ protected AbstractListEditor(Composite parent) {
+ super(parent);
+ }
+
+ protected AbstractListEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+ }
+
+ protected AbstractListEditor(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ protected AbstractListEditor(Composite parent, String label) {
+ super(parent, label);
+ }
+
+ /**
+ * Sets this editor's IObservableList associated to the widget property
+ *
+ * @param widgetObservable
+ * @param targetToModel
+ * the IConverter to convert data from Widget to Model
+ * @param modelToTarget
+ * the IConverter to convert data from Model to Widget
+ */
+ protected void setWidgetObservable(IObservableList widgetObservable, IConverter targetToModel, IConverter modelToTarget) {
+ this.widgetObservable = widgetObservable;
+ setConverters(targetToModel, modelToTarget);
+ }
+
+ /**
+ * Sets this editor's IObservableList associated to the widget property
+ *
+ * @param widgetObservable
+ */
+ protected void setWidgetObservable(IObservableList widgetObservable) {
+ this.widgetObservable = widgetObservable;
+ }
+
+ /**
+ * Sets this editor's IObservableList associated to the model property,
+ * and binds it to the Editor's Widget
+ *
+ * @param modelProperty
+ */
+ public void setModelObservable(IObservableList modelProperty) {
+ this.modelProperty = modelProperty;
+ doBinding();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setConverters(IConverter targetToModel, IConverter modelToTarget) {
+ if (targetToModelStrategy == null) {
+ targetToModelStrategy = new UpdateListStrategy();
+ }
+ if (modelToTargetStrategy == null) {
+ modelToTargetStrategy = new UpdateListStrategy();
+ }
+
+ targetToModelStrategy.setConverter(targetToModel);
+ modelToTargetStrategy.setConverter(modelToTarget);
+ }
+
+ /**
+ * Sets the UpdateStrategies for databinding between the widget and the model
+ *
+ * @param targetToModelStrategy
+ * The widget to model Update strategy
+ * @param modelToTargetStrategy
+ * The model to widget Update strategy
+ */
+ public void setUpdateStrategies(UpdateListStrategy targetToModelStrategy, UpdateListStrategy modelToTargetStrategy) {
+ this.targetToModelStrategy = targetToModelStrategy;
+ this.modelToTargetStrategy = modelToTargetStrategy;
+ }
+
+ /**
+ * Binds the Widget Observable to the Model observable property,
+ * using the specified converters or Update strategies when available
+ *
+ * When overriding this method, you should also override {@link #refreshValue()}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.AbstractEditor#doBinding()
+ */
+ @Override
+ protected void doBinding() {
+
+ if (modelProperty == null || widgetObservable == null) {
+ return;
+ }
+
+ binding = getBindingContext().bindList(widgetObservable, modelProperty, targetToModelStrategy, modelToTargetStrategy);
+ }
+
+ @Override
+ protected Object getContextElement() {
+ // Our observables for features of EMF objects are expected to implement IObserving because
+ // the observe the value of the object's feature
+ return (modelProperty instanceof IObserving) ? ((IObserving) modelProperty).getObserved() : null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractReferenceDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractReferenceDialog.java
new file mode 100644
index 00000000000..70ef6df522c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractReferenceDialog.java
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This class allow to define a reference value editor.
+ */
+public abstract class AbstractReferenceDialog extends AbstractValueEditor implements IReferenceValueEditor {
+
+ /**
+ * Boolean to detect direct creation.
+ */
+ protected boolean directCreation;
+
+ /**
+ * Indicates whether the widget requires a value or not. If it is mandatory,
+ * it cannot delete/unset its value
+ */
+ protected boolean mandatory;
+
+ /**
+ * Boolean to determinate if the editors are read-only.
+ */
+ protected boolean readOnly;
+
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ */
+ protected AbstractReferenceDialog(final Composite parent) {
+ super(parent);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style.
+ * @param label
+ * The label.
+ */
+ protected AbstractReferenceDialog(final Composite parent, final int style, final String label) {
+ super(parent, style, label);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style.
+ */
+ protected AbstractReferenceDialog(final Composite parent, final int style) {
+ super(parent, style);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param label
+ * The label.
+ */
+ protected AbstractReferenceDialog(final Composite parent, final String label) {
+ super(parent, label);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#setContentProvider(org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider)
+ */
+ @Override
+ public abstract void setContentProvider(final IStaticContentProvider provider);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#setLabelProvider(org.eclipse.jface.viewers.ILabelProvider)
+ */
+ @Override
+ public abstract void setLabelProvider(final ILabelProvider provider);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#setValueFactory(org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory)
+ */
+ @Override
+ public abstract void setValueFactory(final ReferenceValueFactory factory);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#updateControls()
+ */
+ @Override
+ public abstract void updateControls();
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#setDirectCreation(boolean)
+ */
+ @Override
+ public void setDirectCreation(final boolean directCreation) {
+ this.directCreation = directCreation;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.IReferenceValueEditor#setMandatory(boolean)
+ */
+ @Override
+ public void setMandatory(final boolean mandatory) {
+ this.mandatory = mandatory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#getValue()
+ */
+ @Override
+ public abstract Object getValue();
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#getEditableType()
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#setReadOnly(boolean)
+ */
+ @Override
+ public void setReadOnly(final boolean readOnly) {
+ this.readOnly = readOnly;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractValueEditor.java
new file mode 100644
index 00000000000..2cbb8b44e2f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/AbstractValueEditor.java
@@ -0,0 +1,299 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 402525
+ * Mickaël ADAM (ALL4TEC) mickael.adam@all4tec.net - bug 435415
+ * Christian W. Damus (CEA) - bug 417409
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObserving;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.papyrus.infra.widgets.validator.AbstractValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * An abstract class to represent Single-value Editors. Single-value editors are
+ * based on the Eclipse Databinding Framework They take {@link IObservableValue} s as Input
+ *
+ * @author Camille Letavernier
+ *
+ */
+public abstract class AbstractValueEditor extends AbstractEditor {
+
+ /**
+ * The IObservableValue associated to the model property
+ */
+ protected IObservableValue modelProperty;
+
+ /**
+ * The IObservableValue associated to the widget
+ */
+ protected IObservableValue widgetObservable;
+
+ /**
+ * The UpdateStrategy for binding data from widget to model
+ */
+ protected UpdateValueStrategy targetToModelStrategy;
+
+ /**
+ * The UpdateStrategy for binding data from model to widget
+ */
+ protected UpdateValueStrategy modelToTargetStrategy;
+
+ /**
+ * the Validator for the target
+ */
+ protected AbstractValidator targetValidator;
+
+ /**
+ * the Validator for the model
+ */
+ protected IValidator modelValidator;
+
+ protected boolean errorBinding = false;
+
+ protected ControlDecoration controlDecoration;
+
+ protected static final Color VALID = new Color(Display.getCurrent(), 144, 238, 144); // CSS LightGreen
+
+ protected static final Color DEFAULT = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+
+ protected static final Color EDIT = new Color(Display.getCurrent(), 255, 204, 153); // Orange
+
+ protected static final Color ERROR = new Color(Display.getCurrent(), 255, 153, 153); // Red
+
+ private boolean initialValidation;
+
+ protected AbstractValueEditor(Composite parent) {
+ super(parent);
+ }
+
+ protected AbstractValueEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+ }
+
+ protected AbstractValueEditor(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ protected AbstractValueEditor(Composite parent, String label) {
+ super(parent, label);
+ }
+
+ /**
+ * Sets this editor's IObservableValue associated to the widget property
+ *
+ * @param widgetObservable
+ * @param targetToModel
+ * the IConverter to convert data from Widget to Model
+ * @param modelToTarget
+ * the IConverter to convert data from Model to Widget
+ */
+ protected void setWidgetObservable(IObservableValue widgetObservable, IConverter targetToModel, IConverter modelToTarget) {
+ this.widgetObservable = widgetObservable;
+ setConverters(targetToModel, modelToTarget);
+ }
+
+ /**
+ * Sets this editor's widgetObservable
+ *
+ * @param widgetObservable
+ * The widget observable value
+ * @param commitOnChange
+ * If true, CommitListeners will be notified when the widget
+ * observable changes
+ */
+ protected void setWidgetObservable(IObservableValue widgetObservable, boolean commitOnChange) {
+ this.widgetObservable = widgetObservable;
+ if (commitOnChange) {
+ this.widgetObservable.addChangeListener(new IChangeListener() {
+
+ @Override
+ public void handleChange(ChangeEvent event) {
+ commit();
+ }
+ });
+ }
+ }
+
+ /**
+ * Sets this editor's IObservableValue associated to the widget property
+ *
+ * @param widgetObservable
+ */
+ protected void setWidgetObservable(IObservableValue widgetObservable) {
+ setWidgetObservable(widgetObservable, false);
+ }
+
+ /**
+ * Sets this editor's IObservableValue associated to the model property, and
+ * binds it to the Editor's Widget
+ *
+ * @param modelProperty
+ */
+ public void setModelObservable(IObservableValue modelProperty) {
+ this.modelProperty = modelProperty;
+ doBinding();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setConverters(IConverter targetToModel, IConverter modelToTarget) {
+ if (targetToModelStrategy == null) {
+ targetToModelStrategy = new UpdateValueStrategy();
+ }
+ if (modelToTargetStrategy == null) {
+ modelToTargetStrategy = new UpdateValueStrategy();
+ }
+ targetToModelStrategy.setConverter(targetToModel);
+ modelToTargetStrategy.setConverter(modelToTarget);
+ }
+
+ /**
+ * Sets the UpdateStrategies for databinding between the widget and the
+ * model
+ *
+ * @param targetToModelStrategy
+ * The widget to model Update strategy
+ * @param modelToTargetStrategy
+ * The model to widget Update strategy
+ */
+ public void setUpdateStrategies(UpdateValueStrategy targetToModelStrategy, UpdateValueStrategy modelToTargetStrategy) {
+ this.targetToModelStrategy = targetToModelStrategy;
+ this.modelToTargetStrategy = modelToTargetStrategy;
+ }
+
+ /**
+ * Binds the Widget Observable to the Model observable property, using the
+ * specified converters or Update strategies when available
+ *
+ * When overriding this method, you should also override {@link #refreshValue()}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#doBinding()
+ */
+ @Override
+ protected void doBinding() {
+ if (modelProperty == null || widgetObservable == null) {
+ return;
+ }
+ setBinding();
+ }
+
+ /**
+ * Returns the value from the widget May be used even when the Model
+ * Observable is not set
+ *
+ * @return The current value for this editor
+ */
+ public abstract Object getValue();
+
+ /**
+ * Initialize binding
+ */
+ private void setBinding() {
+ binding = getBindingContext().bindValue(widgetObservable, modelProperty, targetToModelStrategy, modelToTargetStrategy);
+ binding.getValidationStatus().addValueChangeListener(new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(ValueChangeEvent event) {
+ // Don't handle validation changes if we don't have a validator, because then it could only be green and it isn't useful.
+ // Also, if we're showing in a dialog, then our widget may have been disposed already if we're validating a change applied
+ // by hitting the OK button
+ if ((modelValidator) != null) {
+ // Check if the widget is disposed before isReadOnly() to avoid NPE
+ if (!AbstractValueEditor.this.isDisposed() && !isReadOnly()) { // Bug 434787 : Shouldn't not execute the timer thread if the widget is disposed
+ IStatus status = (IStatus) binding.getValidationStatus().getValue(); // Bug 435415 : Update the status only if the widget isn't disposed
+ updateStatus(status);
+
+ // Don't kick the colour if we're just doing the initial validation to show the decoration.
+ // Only trigger the colours on user-initiated edits
+ if (!initialValidation) {
+ changeColorField();
+ }
+ }
+ }
+ }
+
+ });
+ }
+
+ public void updateStatus(IStatus status) {
+ }
+
+ /**
+ * Set the target to model Strategy to after get validation
+ *
+ * @param targetToModelValidator
+ */
+ public void setTargetAfterGetValidator(AbstractValidator targetToModelValidator) {
+ if (targetToModelValidator != null) {
+ targetToModelStrategy.setAfterGetValidator(targetToModelValidator);
+ }
+ }
+
+ /**
+ * Set the model strategy with After get validation
+ * Set the target strategy with before set validation
+ *
+ * @param modelValidator
+ */
+ public void setModelValidator(IValidator targetToModelValidator) {
+ this.modelValidator = targetToModelValidator;
+ targetToModelStrategy.setBeforeSetValidator(targetToModelValidator);
+ modelToTargetStrategy.setAfterGetValidator(targetToModelValidator);
+
+ if ((binding != null) && (this.modelValidator != null)) {
+ final boolean wasInitialValidation = initialValidation;
+ initialValidation = true;
+
+ try {
+ binding.validateModelToTarget();
+ } finally {
+ initialValidation = wasInitialValidation;
+ }
+ }
+ }
+
+ /**
+ * Initialize both strategies with default values
+ */
+ public void setStrategies() {
+ if (modelToTargetStrategy == null) {
+ modelToTargetStrategy = new UpdateValueStrategy();
+ }
+ if (targetToModelStrategy == null) {
+ targetToModelStrategy = new UpdateValueStrategy();
+ }
+ }
+
+ @Override
+ protected Object getContextElement() {
+ // Our observables for features of EMF objects are expected to implement IObserving because
+ // the observe the value of the object's feature
+ return (modelProperty instanceof IObserving) ? ((IObserving) modelProperty).getObserved() : null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCheckbox.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCheckbox.java
new file mode 100644
index 00000000000..31298ad2376
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCheckbox.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.databinding.GrayedCheckboxObservableValue;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Property Editor representing a Boolean value
+ * as a Checkbox.
+ *
+ * @author Camille Letavernier
+ */
+public class BooleanCheckbox extends AbstractValueEditor {
+
+ private final Button checkbox;
+
+ private AggregatedObservable aggregated;
+
+
+ /**
+ *
+ * Constructor. Creates a new Property Editor for a Boolean
+ * value, represented as a Checkbox.
+ *
+ * @param parent
+ * This editor's parent composite
+ * @param style
+ * The style applied to this editor's checkbox
+ */
+ public BooleanCheckbox(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ *
+ * Constructor. Creates a new Property Editor for a Boolean
+ * value, represented as a Checkbox, with the given label
+ *
+ * @param parent
+ * This editor's parent composite
+ * @param style
+ * The style applied to this editor's checkbox
+ * @param label
+ * The label for this editor
+ */
+ public BooleanCheckbox(Composite parent, int style, String label) {
+ super(parent);
+ checkbox = factory.createButton(this, label, SWT.CHECK | style);
+
+ IObservableValue widgetObservable = WidgetProperties.selection().observe(checkbox);
+ setWidgetObservable(widgetObservable, true);
+ GridData gridData = getDefaultLayoutData();
+ checkbox.setLayoutData(gridData);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+
+
+ }
+
+ @Override
+ public void setModelObservable(IObservableValue modelProperty) {
+ IObservableValue newWidgetObservable;
+
+ if (this.widgetObservable != null) {
+ this.widgetObservable.dispose();
+ }
+
+ if (modelProperty instanceof AggregatedObservable) {
+ this.aggregated = (AggregatedObservable) modelProperty;
+ newWidgetObservable = new GrayedCheckboxObservableValue(checkbox, aggregated);
+ } else {
+ newWidgetObservable = WidgetProperties.selection().observe(checkbox);
+ }
+ setWidgetObservable(newWidgetObservable, true);
+ super.setModelObservable(modelProperty);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Boolean.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Boolean getValue() {
+ return checkbox.getSelection();
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ checkbox.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !checkbox.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ checkbox.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void setLabel(String label) {
+ checkbox.setText(label);
+ }
+
+ /**
+ * Sets this widget's value
+ *
+ * @param selected
+ * Whether the checkbox should be selected or not
+ */
+ public void setValue(Boolean selected) {
+ if (modelProperty != null) {
+ modelProperty.setValue(selected);
+ }
+ widgetObservable.setValue(selected);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCombo.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCombo.java
new file mode 100644
index 00000000000..4672085f927
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanCombo.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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.databinding.viewers.ViewerProperties;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.widgets.providers.AbstractStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An editor representing a boolean value as a combo box, with
+ * two options (true / false)
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanCombo extends AbstractValueEditor {
+
+ private ComboViewer viewer;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ */
+ public BooleanCombo(Composite parent) {
+ this(parent, SWT.NONE, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The style of this editor's CCombo
+ * @param label
+ * This editor's label
+ */
+ public BooleanCombo(Composite parent, int style, String label) {
+ super(parent, style, label);
+ CCombo combo = factory.createCCombo(this, style | SWT.BORDER);
+ combo.setBackground(new Color(combo.getDisplay(), 255, 255, 255));
+ combo.setLayoutData(getDefaultLayoutData());
+ combo.setEditable(false);
+ viewer = createComboViewer(combo);
+
+ viewer.setContentProvider(new EncapsulatedContentProvider(new AbstractStaticContentProvider() {
+
+ @Override
+ public Object[] getElements() {
+ return new Boolean[] { Boolean.TRUE, Boolean.FALSE };
+ }
+ }));
+
+ viewer.setInput(""); //$NON-NLS-1$
+
+ setWidgetObservable(ViewerProperties.singleSelection().observe(viewer));
+
+ setCommitOnFocusLost(combo);
+
+ }
+
+ /**
+ * Creates the combo viewer
+ *
+ * @param combo
+ * The parent combo
+ * @return the combo viewer.
+ */
+ protected ComboViewer createComboViewer(CCombo combo) {
+ return new ComboViewer(combo);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The style of this editor's CCombo
+ */
+ public BooleanCombo(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param label
+ * This editor's label
+ */
+ public BooleanCombo(Composite parent, String label) {
+ this(parent, SWT.NONE, label);
+ }
+
+ @Override
+ public Object getValue() {
+ return ((StructuredSelection) viewer.getSelection()).getFirstElement();
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Boolean.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ viewer.getCCombo().setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !viewer.getCCombo().isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ viewer.getCCombo().setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanRadio.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanRadio.java
new file mode 100644
index 00000000000..9b9ba41f4f9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanRadio.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.SelectObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Property Editor representing a Boolean value
+ * as a Radio, with two options (true/false).
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanRadio extends AbstractValueEditor {
+
+ /**
+ * The "true" radio button
+ */
+ protected Button trueRadio;
+
+ /**
+ * The "false" radio button
+ */
+ protected Button falseRadio;
+
+ private ControlDecoration controlDecoration;
+
+
+ /**
+ *
+ * Constructor. Creates a new Property Editor for a Boolean
+ * value, represented by two radio buttons.
+ *
+ * @param parent
+ * This editor's parent composite
+ * @param style
+ * The style applied to this editor's radio buttons
+ */
+ public BooleanRadio(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ *
+ * Constructor. Creates a new Property Editor for a Boolean
+ * value, represented by two radio buttons.
+ *
+ * @param parent
+ * This editor's parent composite
+ * @param style
+ * The style applied to this editor's radio buttons
+ * @param label
+ * The label for this editor
+ */
+ public BooleanRadio(Composite parent, int style, String label) {
+ super(parent, label);
+
+ ((GridLayout) getLayout()).numColumns = 3;
+
+ trueRadio = factory.createButton(this, "true", style | SWT.RADIO); //$NON-NLS-1$
+ trueRadio.setBackground(this.getBackground()); // For Radio buttons, we need to force the color
+
+ falseRadio = factory.createButton(this, "false", style | SWT.RADIO); //$NON-NLS-1$
+ falseRadio.setBackground(this.getBackground()); // For Radio buttons, we need to force the color
+
+ setWidgetObservable(getObservable(), true);
+ controlDecoration = new ControlDecoration(trueRadio, SWT.TOP | SWT.LEFT);
+ GridData gridData = new GridData();
+ trueRadio.setLayoutData(gridData);
+ falseRadio.setLayoutData(gridData);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ }
+
+ /**
+ * Defines a single observable value, encapsulating the ones
+ * from each radio button (true / false)
+ *
+ * @return The encapsulating observable value
+ */
+ private IObservableValue getObservable() {
+ IObservableValue trueObservable = WidgetProperties.selection().observe(trueRadio);
+ IObservableValue falseObservable = WidgetProperties.selection().observe(falseRadio);
+
+ SelectObservableValue observable = new SelectObservableValue();
+ observable.addOption(true, trueObservable);
+ observable.addOption(false, falseObservable);
+
+ return observable;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Boolean.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Boolean getValue() {
+ return trueRadio.getSelection();
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ trueRadio.setEnabled(!readOnly);
+ falseRadio.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !trueRadio.isEnabled() || !falseRadio.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ trueRadio.setToolTipText(text);
+ falseRadio.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanToggle.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanToggle.java
new file mode 100644
index 00000000000..64207141577
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BooleanToggle.java
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A widget to represent boolean values as a Toggle Button.
+ * The Button may have either an Icon or a Text
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanToggle extends AbstractValueEditor {
+
+ private Button toggleButton;
+ private ControlDecoration controlDecoration;
+
+ private BooleanToggle(Composite parent, int style, String label, Image image, String text) {
+ super(parent, SWT.NONE, label);
+
+ toggleButton = factory.createButton(this, null, style | SWT.TOGGLE);
+ setWidgetObservable(WidgetProperties.selection().observe(toggleButton));
+ setCommitOnFocusLost(toggleButton);
+ GridData gridData = new GridData();
+ toggleButton.setLayoutData(gridData);
+
+ toggleButton.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ commit();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+ });
+
+ setText(text);
+ setImage(image);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+
+ controlDecoration = new ControlDecoration(toggleButton, SWT.TOP | SWT.LEFT);
+ }
+
+ public BooleanToggle(Composite parent, int style, String label, String text) {
+ this(parent, style, label, null, text);
+ }
+
+ public BooleanToggle(Composite parent, int style, String label, Image image) {
+ this(parent, style, label, image, null);
+ }
+
+ public BooleanToggle(Composite parent) {
+ this(parent, SWT.NONE, null, null, null);
+ }
+
+ public BooleanToggle(Composite parent, int style) {
+ this(parent, style, null, null, null);
+ }
+
+ /**
+ * Sets this button's text
+ *
+ * @param text
+ * The text to set to this button
+ */
+ public void setText(String text) {
+ if (text != null) {
+ toggleButton.setText(text);
+ }
+ }
+
+ /**
+ * Sets this button's image
+ *
+ * @param image
+ * The image to set to this button
+ */
+ public void setImage(Image image) {
+ if (image != null) {
+ toggleButton.setImage(image);
+ }
+ }
+
+ @Override
+ public Boolean getValue() {
+ return toggleButton.getSelection();
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Boolean.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ toggleButton.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !toggleButton.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ toggleButton.setToolTipText(text);
+ setLabelToolTipText(text);
+ }
+
+ /**
+ * Indicates whether this button should be selected or not
+ *
+ * @param isActive
+ * If true, the button will be selected
+ */
+ public void setValue(boolean isActive) {
+ toggleButton.setSelection(isActive);
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+ // nothing
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault()
+ .getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault()
+ .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+ }
+
+ @Override
+ public void changeColorField() {
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BrowseFileEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BrowseFileEditor.java
new file mode 100644
index 00000000000..854a6e094a8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BrowseFileEditor.java
@@ -0,0 +1,408 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
+import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider;
+import org.eclipse.papyrus.infra.widgets.util.FileUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.FileDialog;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+
+/**
+ * Specific String editor to select a file with unique button.
+ *
+ * @author gpascual
+ *
+ */
+public class BrowseFileEditor extends StringEditor {
+
+ /** Unique button with associated menu to choice where file will be selected. */
+ private Button button = null;
+
+ /** List of accepted file extensions. */
+ private List<String> filterExtensions = new ArrayList<String>();
+
+ /** List of accepted names. */
+ private List<String> filterNames = new ArrayList<String>();
+
+ /** Attribute to allow file from workspace. */
+ private boolean allowWorkspace = true;
+
+ /** Attribute to allow file from file system. */
+ private boolean allowFileSystem = true;
+
+ /** Attribute for writing rights. */
+ private boolean readOnly = false;
+
+ /** Menu of file system. */
+ private MenuItem fileSystemMenuItem = null;
+
+ /** Menu of workspace. */
+ private MenuItem workspaceMenuItem = null;
+
+ /**
+ * Default constructor.
+ *
+ * @param parent
+ * the parent
+ * @param style
+ * the style
+ */
+ public BrowseFileEditor(Composite parent, int style) {
+ super(parent, style);
+ ((GridLayout) getLayout()).numColumns++;
+ button = factory.createButton(this, Messages.StringFileSelector_Browse, SWT.PUSH);
+ button.setLayoutData(new GridData());
+
+
+ final Menu browseMenu = createButtonMenu();
+
+
+
+ // Display menu when user select button
+ button.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ browseMenu.setVisible(true);
+ }
+ });
+
+ }
+
+
+ /**
+ * Creates the button menu.
+ *
+ * @return the menu
+ */
+ private Menu createButtonMenu() {
+ final Menu browseMenu = new Menu(button);
+
+ // Add file system menu
+ fileSystemMenuItem = new MenuItem(browseMenu, SWT.NONE);
+ fileSystemMenuItem.setText("File system");
+ fileSystemMenuItem.addSelectionListener(new SelectionAdapter() {
+
+
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ File file = getFile(text.getText());
+
+ FileDialog dialog = new FileDialog(getShell());
+ if (labelText != null) {
+ dialog.setText(labelText);
+ }
+ dialog.setFileName(file.getAbsolutePath());
+ dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()]));
+ dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()]));
+ String result = dialog.open();
+ if (result == null) { // Cancel
+ return;
+ }
+ setResult(result);
+ }
+ });
+
+ // Add workspace menu
+ workspaceMenuItem = new MenuItem(browseMenu, SWT.NONE);
+ workspaceMenuItem.setText("Workspace");
+ workspaceMenuItem.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ LabelProviderService labelProviderService = new LabelProviderServiceImpl();
+ try {
+ labelProviderService.startService();
+ } catch (ServiceException ex) {
+ Activator.log.error(ex);
+ }
+
+ ILabelProvider labelProvider = labelProviderService.getLabelProvider();
+
+ IFile currentFile = getIFile(text.getText());
+
+ TreeSelectorDialog dialog = new TreeSelectorDialog(getShell());
+ if (labelText != null) {
+ dialog.setTitle(labelText);
+ }
+
+ WorkspaceContentProvider contentProvider = new WorkspaceContentProvider();
+
+ if (!(filterExtensions.isEmpty() || filterNames.isEmpty())) {
+ // The filters have been defined
+ contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); // Reset the default filters
+
+ // Use our own filters
+ for (int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) {
+ contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i));
+ }
+ }
+
+ dialog.setContentProvider(contentProvider);
+ dialog.setLabelProvider(labelProvider);
+
+
+ if (currentFile != null && currentFile.exists()) {
+ dialog.setInitialSelections(new IFile[] { currentFile });
+ }
+
+ int code = dialog.open();
+ if (code == Window.OK) {
+ Object[] result = dialog.getResult();
+ if (result.length > 0) {
+ Object file = result[0];
+ if (file instanceof IFile) {
+ setResult((IFile) file);
+ }
+ }
+ }
+ }
+ });
+
+ return browseMenu;
+ }
+
+
+ /**
+ * Sets the result.
+ *
+ * @param file
+ * the new result
+ */
+ protected void setResult(IFile file) {
+ text.setText(file.getFullPath().toString());
+ notifyChange();
+ }
+
+ /**
+ * Sets the result.
+ *
+ * @param file
+ * the new result
+ */
+ protected void setResult(File file) {
+ text.setText(file.getAbsolutePath());
+ notifyChange();
+ }
+
+ /**
+ * Sets the result.
+ *
+ * @param path
+ * the new result
+ */
+ protected void setResult(String path) {
+ text.setText(path);
+ notifyChange();
+ }
+
+ /**
+ * Gets the file.
+ *
+ * @param path
+ * the path
+ * @return the i file
+ */
+ protected IFile getIFile(String path) {
+ return FileUtil.getIFile(path);
+ }
+
+ /**
+ * Gets the file.
+ *
+ * @param path
+ * the path
+ * @return the file
+ */
+ protected File getFile(String path) {
+ return FileUtil.getFile(path);
+ }
+
+ /**
+ * Sets the filters.
+ *
+ * @param filterExtensions
+ * the filter extensions
+ * @param filterNames
+ * the filter names
+ */
+ public void setFilters(String[] filterExtensions, String[] filterNames) {
+ if (filterExtensions.length != filterNames.length) {
+ // This is a simple warning. Only valid filters will be retained.
+ Activator.log.warn("FilterExtensions and FilterNames do not match");
+ }
+
+ setFilterNames(getFilterLabels(filterNames, filterExtensions));
+ setFilterExtensions(filterExtensions);
+ }
+
+ /**
+ * Gets the filter labels.
+ *
+ * @param filterNames
+ * the filter names
+ * @param filterExtensions
+ * the filter extensions
+ * @return the filter labels
+ */
+ protected String[] getFilterLabels(String[] filterNames, String[] filterExtensions) {
+ int size = Math.min(filterNames.length, filterExtensions.length);
+ String[] filters = new String[size];
+ for (int i = 0; i < size; i++) {
+ filters[i] = filterNames[i] + " (" + filterExtensions[i] + ")";
+ }
+ return filters;
+ }
+
+ /**
+ * Sets the filter extensions.
+ *
+ * @param filterExtensions
+ * the new filter extensions
+ */
+ public void setFilterExtensions(String[] filterExtensions) {
+ this.filterExtensions = Arrays.asList(filterExtensions);
+ }
+
+ /**
+ * Sets the filter names.
+ *
+ * @param filterNames
+ * the new filter names
+ */
+ public void setFilterNames(String[] filterNames) {
+ this.filterNames = Arrays.asList(filterNames);
+ }
+
+ /**
+ * Adds the filtered extension.
+ *
+ * @param filteredExtension
+ * the filtered extension
+ * @param filterName
+ * the filter name
+ */
+ public void addFilteredExtension(String filteredExtension, String filterName) {
+ if (filteredExtension != null) {
+ if (filterName == null) {
+ filterName = filteredExtension;
+ }
+
+ filterExtensions.add(filteredExtension);
+ filterNames.add(filterName);
+ }
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.StringEditor#getEditableType()
+ *
+ * @return
+ */
+
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.StringEditor#setReadOnly(boolean)
+ *
+ * @param readOnly
+ */
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ super.setReadOnly(readOnly);
+ this.readOnly = readOnly;
+ updateButtons();
+ }
+
+ /**
+ * Sets the allow workspace.
+ *
+ * @param allowWorkspace
+ * the new allow workspace
+ */
+ public void setAllowWorkspace(boolean allowWorkspace) {
+ this.allowWorkspace = allowWorkspace;
+ updateButtons();
+ }
+
+ /**
+ * Sets the allow file system.
+ *
+ * @param allowFileSystem
+ * the new allow file system
+ */
+ public void setAllowFileSystem(boolean allowFileSystem) {
+
+ this.allowFileSystem = allowFileSystem;
+ updateButtons();
+ }
+
+ /**
+ * Sets the button label.
+ *
+ * @param label
+ * the new button label
+ */
+ public void setButtonLabel(String label) {
+ button.setText(label);
+ }
+
+ /**
+ * Gets the button label.
+ *
+ * @return the button label
+ */
+ public String getButtonLabel() {
+ return button.getText();
+ }
+
+ /**
+ * Update buttons.
+ */
+ private void updateButtons() {
+ boolean enableWorkspace = !readOnly && allowWorkspace;
+ boolean enableFileSystem = !readOnly && allowFileSystem;
+ // ((GridData)browseWorkspace.getLayoutData()).exclude = !allowWorkspace;
+ // ((GridData)browse.getLayoutData()).exclude = !allowFileSystem;
+ fileSystemMenuItem.setEnabled(enableWorkspace);
+ workspaceMenuItem.setEnabled(enableFileSystem);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleIntegerEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleIntegerEditor.java
new file mode 100644
index 00000000000..c281c5697be
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleIntegerEditor.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.papyrus.infra.widgets.selectors.IntegerSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A compact editor for multivalued Integer attributes
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class CompactMultipleIntegerEditor extends CompactMultipleValueEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ */
+ public CompactMultipleIntegerEditor(Composite parent, int style) {
+ this(parent, style, true, false, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ * @param ordered
+ * True if the values should be ordered
+ * @param unique
+ * True if the values should be unique
+ */
+ public CompactMultipleIntegerEditor(Composite parent, int style, boolean ordered, boolean unique) {
+ this(parent, style, ordered, unique, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ * @param ordered
+ * True if the values should be ordered
+ * @param unique
+ * True if the values should be unique
+ * @param separator
+ * The String used to separate the different values in the value label
+ * @param label
+ * The editor's label
+ */
+ public CompactMultipleIntegerEditor(Composite parent, int style, boolean ordered, boolean unique, String separator, String label) {
+ super(parent, style, new IntegerSelector(), ordered, unique, separator, label);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleReferenceEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleReferenceEditor.java
new file mode 100644
index 00000000000..25591a493b8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleReferenceEditor.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Property Editor representing a MultipleReference
+ * as a label with the selected values. If the list
+ * of values is too long, it gets truncated.
+ * The values can be edited via a selection dialog.
+ * This widget is useful when there is not much vertical space available,
+ * and a MultipleReferenceEditor can not be used.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class CompactMultipleReferenceEditor extends CompactMultipleValueEditor {
+
+ /**
+ * The selector for the available values
+ */
+ protected ReferenceSelector selector;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The widget in which this editor is created
+ * @param style
+ * The style for this editor's control
+ */
+ public CompactMultipleReferenceEditor(Composite parent, int style) {
+ this(parent, style, true, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The widget in which this editor is created
+ * @param style
+ * The style for this editor's control
+ * @param ordered
+ * True if the multivalued property is ordered
+ * @param unique
+ * True if the multivalued property needs unique values
+ */
+ public CompactMultipleReferenceEditor(Composite parent, int style, boolean ordered, boolean unique) {
+ super(parent, style, new ReferenceSelector(unique), ordered, unique);
+ this.selector = (ReferenceSelector) super.selector;
+ }
+
+ /**
+ * Sets the Content and Label providers for this widget.
+ *
+ * The label provider is used in each place where the values can
+ * be displayed
+ * The content provider is used to display the items that can be selected
+ *
+ * @param contentProvider
+ * The content provider for this widget
+ * @param labelProvider
+ * The label provider for this widget
+ */
+ public void setProviders(IStaticContentProvider contentProvider, ILabelProvider labelProvider) {
+ selector.setContentProvider(contentProvider);
+ selector.setLabelProvider(labelProvider);
+ super.setLabelProvider(labelProvider);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleStringEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleStringEditor.java
new file mode 100644
index 00000000000..e9c958f2c6d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleStringEditor.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.papyrus.infra.widgets.selectors.StringSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A compact editor for multivalued String attributes
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class CompactMultipleStringEditor extends CompactMultipleValueEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ */
+ public CompactMultipleStringEditor(Composite parent, int style) {
+ this(parent, style, true, false, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ * @param ordered
+ * True if the values should be ordered
+ * @param unique
+ * True if the values should be unique
+ */
+ public CompactMultipleStringEditor(Composite parent, int style, boolean ordered, boolean unique) {
+ this(parent, style, ordered, unique, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor will be displayed
+ * @param style
+ * The value label's style
+ * @param ordered
+ * True if the values should be ordered
+ * @param unique
+ * True if the values should be unique
+ * @param separator
+ * The String used to separate the different values in the value label
+ * @param label
+ * The editor's label
+ */
+ public CompactMultipleStringEditor(Composite parent, int style, boolean ordered, boolean unique, String separator, String label) {
+ super(parent, style, new StringSelector(), ordered, unique, separator, label);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleValueEditor.java
new file mode 100644
index 00000000000..c17a3329f04
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompactMultipleValueEditor.java
@@ -0,0 +1,288 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+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.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+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.Label;
+
+/**
+ * A Property Editor representing a multivalued property as a label with the
+ * selected values. If the list of values is too long, it is truncated. The
+ * values can be edited via a selection dialog. This widget is useful when there
+ * is not much vertical space available, and a MultipleValueEditor can not be
+ * used.
+ */
+public class CompactMultipleValueEditor extends AbstractListEditor implements IChangeListener, DisposeListener, SelectionListener {
+
+ /**
+ * The default value separator in the value label
+ */
+ protected static final String DEFAULT_VALUE_SEPARATOR = ", "; //$NON-NLS-1$
+
+ /**
+ * The label for displayed the selected values
+ */
+ protected Label valueLabel;
+
+ /**
+ * The button to open a dialog for editing the values
+ */
+ protected Button edit;
+
+ /**
+ * The label provider for this editor. Also used by the dialog.
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The string used for separating values in the value label
+ */
+ protected String separator;
+
+ /**
+ * The Dialog displayed when adding new elements
+ */
+ protected MultipleValueSelectorDialog dialog;
+
+ /**
+ * The element selector for the dialog
+ */
+ protected IElementSelector selector;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The widget in which this editor is created
+ * @param style
+ * The style for this editor's control
+ * @param selector
+ * The IElementSelector for this editor's selection dialog
+ */
+ public CompactMultipleValueEditor(Composite parent, int style, IElementSelector selector) {
+ this(parent, style, selector, false, false, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The widget in which this editor is created
+ * @param style
+ * The style for this editor's control
+ * @param selector
+ * The element selector to be used in the selection dialog
+ * @param ordered
+ * True if the multivalued property is ordered
+ * @param unique
+ * True if the multivalued property needs unique values
+ */
+ public CompactMultipleValueEditor(Composite parent, int style, IElementSelector selector, boolean ordered, boolean unique) {
+ this(parent, style, selector, ordered, unique, DEFAULT_VALUE_SEPARATOR, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The widget in which this editor is created
+ * @param style
+ * The style for this editor's control
+ * @param selector
+ * The element selector to be used in the selection dialog
+ * @param ordered
+ * True if the multivalued property is ordered
+ * @param unique
+ * True if the multivalued property needs unique values
+ * @param separator
+ * The string used to separate values in the display label
+ * @param label
+ * The label for this editor
+ */
+ public CompactMultipleValueEditor(Composite parent, int style, IElementSelector selector, boolean ordered, boolean unique, String separator, String label) {
+ super(parent, label);
+
+ ((GridLayout) getLayout()).numColumns = 3;
+
+ valueLabel = factory.createLabel(this, null, style);
+ valueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ edit = new Button(this, SWT.PUSH);
+ edit.setText("..."); //$NON-NLS-1$
+ edit.addSelectionListener(this);
+ edit.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
+
+ this.selector = selector;
+ dialog = new MultipleValueSelectorDialog(parent.getShell(), selector, unique);
+
+ labelProvider = new LabelProvider();
+ this.separator = separator;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Collection.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doBinding() {
+ // We don't do a real Databinding in this case
+ modelProperty.addChangeListener(this);
+ handleChange(null);
+ }
+
+ /**
+ * Sets the label provider for this editor
+ *
+ * @param provider
+ * The label provider for this editor
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ dialog.setLabelProvider(provider);
+ this.labelProvider = provider;
+ }
+
+ /**
+ * Refreshes the Label when a change occurs on the ObservableList
+ *
+ * @see org.eclipse.core.databinding.observable.IChangeListener#handleChange(org.eclipse.core.databinding.observable.ChangeEvent)
+ *
+ * @param event
+ */
+ @Override
+ public void handleChange(ChangeEvent event) {
+ if (modelProperty != null) {
+
+ List<String> labels = new LinkedList<String>();
+ for (Object element : modelProperty) {
+ labels.add(labelProvider.getText(element));
+ }
+
+ valueLabel.setText(createValueLabel(labels));
+ }
+ }
+
+ /**
+ * Creates the text for the value label of this editor
+ *
+ * @param labels
+ * The labels for each selected element
+ * @return The concatenated label
+ */
+ protected String createValueLabel(List<String> labels) {
+ if (labels.size() == 0) {
+ return ""; //$NON-NLS-1$
+ }
+
+ String result = labels.get(0);
+ for (int i = 1; i < labels.size(); i++) {
+ result += separator + labels.get(i);
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if (modelProperty != null) {
+ modelProperty.removeChangeListener(this);
+ }
+ super.dispose();
+ }
+
+ /**
+ * {@inheritDoc} Handles the event when the edit button is pressed
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ dialog.setContextElement(getContextElement());
+ dialog.setInitialSelections(modelProperty.toArray());
+ int returnCode = dialog.open();
+ if (returnCode == Window.CANCEL) {
+ return;
+ }
+
+ modelProperty.clear();
+
+ Object[] result = dialog.getResult();
+ if (result == null) {
+ return;
+ }
+
+ java.util.List<Object> resultElements = new LinkedList<Object>();
+ for (Object r : result) {
+ resultElements.add(r);
+ }
+
+ modelProperty.addAll(resultElements);
+ }
+
+ /**
+ * {@inheritDoc} Ignored
+ */
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ valueLabel.setEnabled(!readOnly);
+ edit.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !valueLabel.isEnabled() || !edit.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ valueLabel.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void refreshValue() {
+ handleChange(null);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextMultipleReferenceEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextMultipleReferenceEditor.java
new file mode 100644
index 00000000000..7103ed3b46e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextMultipleReferenceEditor.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.papyrus.infra.widgets.databinding.CompletionStyledTextMultiReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ *
+ * An editor for multivalued references, with a string editor in addition. This editor should be used when
+ * there is enough vertical space available. If the vertical space is limited,
+ * CompactMultipleReferenceEditor should be used instead.
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class CompletionStyledTextMultipleReferenceEditor extends MultipleReferenceEditor implements ISetPapyrusConverter {
+
+ /**
+ * the embedded string editor
+ */
+ private CompletionStyledTextStringEditor editor;
+
+ /**
+ * the converter to use
+ */
+ private IPapyrusConverter converter;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ * @param ordered
+ * @param unique
+ * @param label
+ */
+ public CompletionStyledTextMultipleReferenceEditor(Composite parent, int style, boolean ordered, boolean unique, String label) {
+ super(parent, style, ordered, unique, label);
+ addStyledTextSection(parent, style);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ * @param label
+ */
+ public CompletionStyledTextMultipleReferenceEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+ addStyledTextSection(parent, style);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public CompletionStyledTextMultipleReferenceEditor(Composite parent, int style) {
+ super(parent, style);
+ addStyledTextSection(parent, style);
+ }
+
+ /**
+ *
+ * @param parent
+ * @param style
+ */
+ protected void addStyledTextSection(Composite parent, int style) {
+ editor = new CompletionStyledTextStringEditor(this, style | SWT.BORDER);
+ GridData treeData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ treeData.horizontalSpan = 2;
+ editor.setLayoutData(treeData);
+ }
+
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.MultipleValueEditor#setModelObservable(org.eclipse.core.databinding.observable.list.IObservableList)
+ *
+ * @param modelProperty
+ */
+ @Override
+ public void setModelObservable(IObservableList modelProperty) {
+ super.setModelObservable(modelProperty);
+ CompletionStyledTextMultiReferenceDialogObservableValue styledTextObservable = new CompletionStyledTextMultiReferenceDialogObservableValue(editor, editor.getText(), modelProperty, SWT.FocusOut);
+ styledTextObservable.setPapyrusConverter(converter);
+ styledTextObservable.addChangeListener(new IChangeListener() {
+
+ @Override
+ public void handleChange(org.eclipse.core.databinding.observable.ChangeEvent event) {
+ commit();
+ }
+ });
+ editor.setValue(modelProperty);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter#setPapyrusConverter(org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter)
+ *
+ * @param converter
+ */
+ @Override
+ public void setPapyrusConverter(IPapyrusConverter converter) {
+ this.converter = converter;
+ this.editor.setPapyrusConverter(converter);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextReferenceDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextReferenceDialog.java
new file mode 100644
index 00000000000..8c7847d3b0a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextReferenceDialog.java
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.infra.widgets.databinding.CompletionStyledTextReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Vincent Lorenzo
+ *
+ */
+public class CompletionStyledTextReferenceDialog extends StyledTextReferenceDialog implements ISetPapyrusConverter {
+ /**
+ * the content assist helper used for the completion
+ */
+ protected IPapyrusConverter parser;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public CompletionStyledTextReferenceDialog(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.StyledTextReferenceDialog#createStyledTextStringEditor(org.eclipse.swt.widgets.Composite, java.lang.String, int)
+ *
+ * @param parent
+ * @param initialValue
+ * @param style
+ * @return
+ */
+ protected StyledTextStringEditor createStyledTextStringEditor(Composite parent, String initialValue, int style) {
+ StyledTextStringEditor editor = new CompletionStyledTextStringEditor(parent, style);
+ editor.setValue(initialValue);
+ return editor;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.StyledTextReferenceDialog#createWidgetObservable(org.eclipse.core.databinding.observable.value.IObservableValue)
+ *
+ * @param modelProperty
+ * @return
+ */
+ protected IObservableValue createWidgetObservable(IObservableValue modelProperty) {
+ CompletionStyledTextReferenceDialogObservableValue val = new CompletionStyledTextReferenceDialogObservableValue(this, this.styledTextStringEditor.getText(), modelProperty, SWT.FocusOut);
+ val.setPapyrusConverter(parser);
+ return val;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter#setPapyrusConverter(org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter)
+ *
+ * @param parser
+ */
+ @Override
+ public void setPapyrusConverter(IPapyrusConverter parser) {
+ this.parser = parser;
+ ((CompletionStyledTextStringEditor) styledTextStringEditor).setPapyrusConverter(parser);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextStringEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextStringEditor.java
new file mode 100644
index 00000000000..367b67aa907
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/CompletionStyledTextStringEditor.java
@@ -0,0 +1,175 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.validator.AbstractValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * @author Vincent Lorenzo
+ *
+ */
+public class CompletionStyledTextStringEditor extends StyledTextStringEditor implements ISetPapyrusConverter {
+
+ /**
+ * This wrapper provides a text field with completion
+ */
+ private StringEditorWithCompletionWrapper wrapper;
+
+ /**
+ * the parser to use
+ */
+ protected IPapyrusConverter parser;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ * @param heighHint
+ * @param widthHint
+ */
+ public CompletionStyledTextStringEditor(Composite parent, int style, int heighHint, int widthHint) {
+ super(parent, style, heighHint, widthHint);
+ createReferenceTargetValidator();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ * @param label
+ * @param heighHint
+ * @param widthHint
+ */
+ public CompletionStyledTextStringEditor(Composite parent, int style, String label, int heighHint, int widthHint) {
+ super(parent, style, label, heighHint, widthHint);
+ createReferenceTargetValidator();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ * @param label
+ */
+ public CompletionStyledTextStringEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+ createReferenceTargetValidator();
+ }
+
+
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.StyledTextStringEditor#setValue(java.lang.Object)
+ *
+ * @param value
+ */
+ @Override
+ public void setValue(Object value) {
+ if (parser != null && value instanceof Collection<?>) {
+ String val = parser.canonicalToEditValue(value, 0);
+ super.setValue(val);
+ } else {
+ super.setValue(value);
+ }
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public CompletionStyledTextStringEditor(Composite parent, int style) {
+ super(parent, style);
+ createReferenceTargetValidator();
+ }
+
+ protected void notifyChange() {
+
+ text.notifyListeners(SWT.FocusOut, new Event());
+
+ // added to update the status when we use the completion
+ if (targetValidator != null) {
+ IStatus status = targetValidator.validate(text.getText());
+ updateStatus(status);
+ }
+ commit();
+ changeColorField();
+ }
+
+ /**
+ * create the validator for the text field
+ */
+ protected void createReferenceTargetValidator() {
+ targetValidator = new AbstractValidator() {
+
+ @Override
+ public IStatus validate(Object value) {
+ if (parser == null) {
+ return Status.OK_STATUS;
+ }
+ if (value instanceof String) {
+ return parser.isValidEditString((String) value);
+ }
+ // not possible
+ return new Status(IStatus.ERROR, org.eclipse.papyrus.infra.widgets.Activator.PLUGIN_ID, "Impossible case"); //$NON-NLS-1$
+ }
+ };
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.StyledTextStringEditor#createStyledText(org.eclipse.swt.widgets.Composite, java.lang.String, int)
+ *
+ * @param parent
+ * @param value
+ * @param style
+ * @return
+ */
+ @Override
+ public StyledText createStyledText(Composite parent, String value, int style) {
+ this.wrapper = new StringEditorWithCompletionWrapper(parent, style);
+ return wrapper.getTextWidget();
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter#setPapyrusConverter(org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter)
+ *
+ * @param parser
+ */
+ public void setPapyrusConverter(IPapyrusConverter parser) {
+ this.parser = parser;
+ this.wrapper.setPapyrusConverter(parser);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/DoubleEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/DoubleEditor.java
new file mode 100644
index 00000000000..d76d447681b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/DoubleEditor.java
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.validator.RealValidator;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * An editor representing a float value as a text box
+ *
+ * @author Camille Letavernier
+ */
+public class DoubleEditor extends StringEditor {
+
+ private IConverter targetToModelConverter;
+
+ /**
+ *
+ * Constructs an Editor for a Double value. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which the editor is created
+ * @param style
+ * The Text's style
+ */
+ public DoubleEditor(Composite parent, int style) {
+ super(parent, style);
+
+ targetValidator = new RealValidator();
+ targetToModelConverter = new IConverter() {
+
+ @Override
+ public Object getFromType() {
+ return String.class;
+ }
+
+ @Override
+ public Object getToType() {
+ return Double.class;
+ }
+
+ @Override
+ public Double convert(Object fromObject) {
+ if (fromObject instanceof String) {
+ String newString = ((String) fromObject)
+ .replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ return Double.parseDouble(newString);
+ } catch (NumberFormatException ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+ return null;
+ }
+
+ };
+
+ IConverter doubleToString = new IConverter() {
+
+ @Override
+ public Object getFromType() {
+ return Double.class;
+ }
+
+ @Override
+ public Object getToType() {
+ return String.class;
+ }
+
+ @Override
+ public Object convert(Object fromObject) {
+ if (fromObject instanceof Double) {
+ return Double.toString((Double) fromObject);
+ }
+ return ""; //$NON-NLS-1$
+ }
+ };
+ setValidateOnDelay(true);
+ setConverters(targetToModelConverter, doubleToString);
+ setTargetAfterGetValidator(targetValidator);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Double.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Double getValue() {
+ try {
+ return (Double) targetToModelConverter.convert(super.getValue());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EditorParentComposite.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EditorParentComposite.java
new file mode 100644
index 00000000000..515a0c110a6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EditorParentComposite.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+/**
+ * The top parent composite for the assembly of tabbed property sheet pages based on the XWT properties model.
+ * Amongst other possible services, this composite works around problems in focus management on some platforms.
+ */
+public class EditorParentComposite extends Composite {
+
+ public EditorParentComposite(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ @Override
+ public boolean setFocus() {
+ Control focusVetoControl = AbstractEditor.FocusVeto.getFocusVetoControl(this);
+
+ if (focusVetoControl != null) {
+ // Don't let me or another control within me take focus
+ return false;
+ }
+
+ return super.setFocus();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumCombo.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumCombo.java
new file mode 100644
index 00000000000..4b22a020676
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumCombo.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An editor representing an Enumeration as a Combo
+ * This Editor needs a ContentProvider describing the Enumerated values,
+ * and an optional label provider
+ *
+ * @author Camille Letavernier
+ */
+public class EnumCombo extends ReferenceCombo {
+
+ /**
+ *
+ * Constructs an editor for an Enumeration. The widget is a CCombo.
+ *
+ * @param parent
+ * The composite is which this editor is created
+ * @param style
+ * The CCombo's style
+ */
+ public EnumCombo(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /**
+ *
+ * Constructs an editor for an Enumeration. The widget is a CCombo.
+ *
+ * @param parent
+ * The composite is which this editor is created
+ * @param style
+ * The CCombo's style
+ * @param label
+ * The editor's label
+ */
+ public EnumCombo(Composite parent, int style, String label) {
+ super(parent, style, label);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumRadio.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumRadio.java
new file mode 100644
index 00000000000..5543eaa68d3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/EnumRadio.java
@@ -0,0 +1,261 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.SelectObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.MapLabelProvider;
+import org.eclipse.papyrus.infra.widgets.providers.StaticContentProvider;
+import org.eclipse.swt.SWT;
+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;
+
+/**
+ * An editor representing an Enumeration as a list of Radio Buttons
+ * If there are many possible values, it is probably more judicious to use an
+ * EnumCombo.
+ * This Editor needs a ContentProvider describing the Enumerated values,
+ * and an optional label provider.
+ *
+ * @author Camille Letavernier
+ *
+ * @see EnumCombo
+ */
+public class EnumRadio extends AbstractValueEditor {
+
+ protected IStaticContentProvider contentProvider;
+
+ protected Composite buttonsArea;
+
+ protected ILabelProvider labelProvider = new LabelProvider();
+
+ protected final Map<Button, Object> values = new HashMap<Button, Object>();
+
+ protected int numColumns = -1;
+
+ private ControlDecoration controlDecoration;
+
+ public EnumRadio(Composite parent, int style) {
+ this(parent, SWT.NONE, null);
+ }
+
+ public EnumRadio(Composite parent, int style, String label) {
+ super(parent, style, label);
+ buttonsArea = factory.createComposite(this);
+ GridData gridData = getDefaultLayoutData();
+ buttonsArea.setLayoutData(gridData);
+ GridLayout layout = new GridLayout(1, true);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ buttonsArea.setLayout(layout);
+ factory.createCLabel(buttonsArea, Messages.EnumRadio_NoValue);
+ controlDecoration = new ControlDecoration(buttonsArea, SWT.TOP | SWT.LEFT);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+
+ }
+
+
+ /**
+ * Sets the content provider for this editor. The Content provider should
+ * specify the values that can be set for this property
+ *
+ * @param contentProvider
+ * The Content provider returning the available values for this editor
+ * @param labelProvider
+ * The label provider returning a label for each value of the
+ * content provider. If null, a default label provider will be used
+ */
+ public void setProviders(IStaticContentProvider contentProvider, ILabelProvider labelProvider) {
+ this.contentProvider = contentProvider;
+ if (labelProvider != null) {
+ this.labelProvider = labelProvider;
+ }
+
+ disposeButtons();
+ if (widgetObservable != null) {
+ widgetObservable.dispose();
+ }
+
+ SelectObservableValue observable = new SelectObservableValue();
+ for (Object value : contentProvider.getElements()) {
+ Button button = factory.createButton(buttonsArea, labelProvider.getText(value), SWT.RADIO);
+ button.setBackground(buttonsArea.getBackground()); // For Radio buttons, we need to force the color
+ button.setData(value);
+ button.setToolTipText(toolTipText);
+ IObservableValue buttonObservable = WidgetProperties.selection().observe(button);
+ observable.addOption(value, buttonObservable);
+
+ values.put(button, value);
+ }
+
+ setWidgetObservable(observable, true);
+ updateLayout();
+
+ doBinding();
+ }
+
+ protected void disposeButtons() {
+ for (Control control : buttonsArea.getChildren()) {
+ control.dispose();
+ }
+ if (binding != null) {
+ binding.dispose();
+ }
+ values.clear();
+ }
+
+ /**
+ * Sets the max number of elements per line for this editor
+ *
+ * @param numColumns
+ * The max number of elements per line. May be -1 if there should
+ * be a single line of elements
+ */
+ public void setNumColumns(int numColumns) {
+ this.numColumns = numColumns;
+ updateLayout();
+ }
+
+ private void updateLayout() {
+ GridLayout gridLayout = (GridLayout) buttonsArea.getLayout();
+ gridLayout.numColumns = numColumns > 0 ? numColumns : values.size();
+ gridLayout.makeColumnsEqualWidth = numColumns > 0;
+
+ updateLabelLayout();
+ }
+
+ private void updateLabelLayout() {
+ if (label == null || label.isDisposed()) {
+ return;
+ }
+
+ if (numColumns == -1) {
+ ((GridData) label.getLayoutData()).verticalAlignment = SWT.CENTER;
+ } else {
+ ((GridData) label.getLayoutData()).verticalAlignment = SWT.BEGINNING;
+ }
+ }
+
+ @Override
+ protected void createLabel(String label) {
+ super.createLabel(label);
+ updateLabelLayout();
+ }
+
+ @Override
+ public Object getValue() {
+ for (Button button : values.keySet()) {
+ if (button.getSelection()) {
+ return values.get(button);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ for (Button button : values.keySet()) {
+ button.setEnabled(!readOnly);
+ }
+ buttonsArea.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !buttonsArea.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ for (Button button : values.keySet()) {
+ button.setToolTipText(text);
+ }
+ super.setLabelToolTipText(text);
+ }
+
+ public void setValue(Object value) {
+ if (modelProperty != null) {
+ modelProperty.setValue(value);
+ }
+ if (widgetObservable != null) {
+ widgetObservable.setValue(value);
+ } else {
+ for (Button button : values.keySet()) {
+ if (values.get(button) == value) {
+ button.setSelection(true);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Use a Map instead of content providers to define the selectable elements
+ * The keys are the semantic objects (contentProvider), and the values are
+ * the labels (labelProvider)
+ *
+ * @param objectsAndLabels
+ */
+ public void setEnumValues(Map<Object, String> objectsAndLabels) {
+ StaticContentProvider provider = new StaticContentProvider(objectsAndLabels.keySet().toArray());
+ LabelProvider labelProvider = new MapLabelProvider(objectsAndLabels);
+ setProviders(provider, labelProvider);
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/FloatEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/FloatEditor.java
new file mode 100644
index 00000000000..cef28a4785e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/FloatEditor.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.infra.widgets.editors;
+
+import java.util.Locale;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.conversion.NumberToStringConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.swt.widgets.Composite;
+
+import com.ibm.icu.text.NumberFormat;
+
+/**
+ * An editor representing a float value as a text box
+ *
+ * @author Camille Letavernier
+ */
+public class FloatEditor extends StringEditor {
+
+ private IConverter targetToModelConverter;
+
+ /**
+ *
+ * Constructs an Editor for a Float value. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which the editor is created
+ * @param style
+ * The Text's style
+ */
+ public FloatEditor(Composite parent, int style) {
+ super(parent, style);
+
+ targetToModelConverter = StringToNumberConverter.toFloat(NumberFormat.getInstance(Locale.ENGLISH), true);
+ setConverters(targetToModelConverter, NumberToStringConverter.fromFloat(NumberFormat.getInstance(Locale.ENGLISH), true));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Float.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Float getValue() {
+ try {
+ return (Float) targetToModelConverter.convert(super.getValue());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ICommitListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ICommitListener.java
new file mode 100644
index 00000000000..8ac36a3d56f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ICommitListener.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.IObservable;
+
+
+/**
+ * An interface for listening "Commit" events on Editors
+ * This is used to implement transactions when using some editors (Especially {@link MultipleValueEditor}s)
+ * When using a CommitListener, the {@link IObservable} should not directly execute
+ * commands when its methods are called, but instead wait for a commit event.
+ *
+ * @author Camille Letavernier
+ */
+public interface ICommitListener {
+
+ /**
+ * Indicates that the implementer should apply the list of operations
+ * received since the last commit
+ *
+ * @param editor
+ * The editor that sent the commit event
+ */
+ public void commit(AbstractEditor editor);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelectionListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelectionListener.java
new file mode 100644
index 00000000000..d4acffd0630
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelectionListener.java
@@ -0,0 +1,18 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+
+public interface IElementSelectionListener {
+
+ public void addElements(Object[] elements);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelector.java
new file mode 100644
index 00000000000..7af7f758a53
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IElementSelector.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.infra.widgets.editors;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An interface for defining widgets that can return
+ * some values.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IElementSelector {
+
+ /**
+ *
+ * @return The currently selected elements
+ */
+ public Object[] getSelectedElements();
+
+ /**
+ * Sets the elements that have already been chosen.
+ *
+ * @param elements
+ */
+ public void setSelectedElements(Object[] elements);
+
+ /**
+ *
+ * @return all displayed elements. If the widget uses a filter,
+ * only the filtered elements should be returned
+ */
+ public Object[] getAllElements();
+
+ /**
+ * Creates the widgets to display this selector
+ *
+ * @param parent
+ */
+ public void createControls(Composite parent);
+
+ /**
+ * Handles the "newObjectCreated" event
+ *
+ * @param newObject
+ * The object that has been created
+ */
+ public void newObjectCreated(Object newObject);
+
+ /**
+ * Clears this selector. Removes all temporary elements that
+ * may have been created.
+ */
+ public void clearTemporaryElements();
+
+ /**
+ * Adds a new listener to this selector.
+ * The selector can inform the listener that new elements have
+ * been selected
+ *
+ * @param listener
+ */
+ public void addElementSelectionListener(IElementSelectionListener listener);
+
+ /**
+ * Removes the element selection listener
+ *
+ * @param listener
+ *
+ * @see {@link #addElementSelectionListener(IElementSelectionListener)}
+ */
+ public void removeElementSelectionListener(IElementSelectionListener listener);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IReferenceValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IReferenceValueEditor.java
new file mode 100644
index 00000000000..a546674dfea
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IReferenceValueEditor.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+
+/**
+ * This interface allow to define the reference value editor methods to implements.
+ */
+public interface IReferenceValueEditor {
+
+ /**
+ * Updates the buttons' status
+ */
+ void updateControls();
+
+ /**
+ * Updates the displayed label for the current value
+ */
+ void updateLabel();
+
+ /**
+ * Sets the Content provider for this editor
+ *
+ * @param provider
+ * The content provider used to retrieve the possible values for this Reference.
+ */
+ void setContentProvider(final IStaticContentProvider provider);
+
+ /**
+ * Sets the Label provider for this editor If the label provider is null, a
+ * default one will be used. The same label provider is used for both the
+ * editor's label and the selection dialog.
+ *
+ * @param provider
+ * The label provider.
+ */
+ void setLabelProvider(final ILabelProvider provider);
+
+ /**
+ * Sets the factory.
+ *
+ * @param factory
+ * The reference value factory.
+ */
+ void setValueFactory(final ReferenceValueFactory factory);
+
+ /**
+ * Sets the direct creation value.
+ *
+ * @param directCreation
+ * Boolean to determinate the direct creation value.
+ */
+ void setDirectCreation(final boolean directCreation);
+
+ /**
+ * Sets the mandatory.
+ *
+ * @param mandatory
+ * The mandatory boolean value.
+ */
+ void setMandatory(final boolean mandatory);
+
+ /**
+ * Sets the read only value.
+ *
+ * @param readOnly
+ * The read only value.
+ */
+ void setReadOnly(final boolean readOnly);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ITreeSelectorDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ITreeSelectorDialog.java
new file mode 100644
index 00000000000..1a15448fd5f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ITreeSelectorDialog.java
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider;
+
+
+
+public interface ITreeSelectorDialog {
+
+ /**
+ * Sets the label provider for this dialog
+ *
+ * @param provider
+ */
+ public void setLabelProvider(ILabelProvider provider);
+
+ /**
+ * Sets the ContentProvider for this dialog
+ * The ContentProvider may be a {@link IHierarchicContentProvider}
+ *
+ * @param provider
+ * The content provider for this dialog. May be a {@link IHierarchicContentProvider}
+ */
+ public void setContentProvider(ITreeContentProvider provider);
+
+ /**
+ * Sets the description for this Dialog. The description is displayed on
+ * top of the dialog
+ *
+ * @param description
+ * The description for this dialog
+ */
+ public void setDescription(String description);
+
+ /**
+ * Sets the input object for this dialog's TreeViewer
+ *
+ * @param input
+ */
+ public void setInput(Object input);
+
+ /**
+ * Sets the initial selected value for this dialog
+ *
+ * @param singletonList
+ */
+ public void setInitialElementSelections(List selectedElements);
+
+
+ /**
+ * Opens the dialog's window, and returns its return code
+ *
+ * @return the return code
+ *
+ * @see #create()
+ */
+ public int open();
+
+ /**
+ * Returns the list of selections made by the user, or <code>null</code> if the selection was canceled.
+ *
+ * @return the array of selected elements, or <code>null</code> if Cancel
+ * was pressed
+ */
+ public Object[] getResult();
+
+ /**
+ * Sets the title for this dialog.
+ *
+ * @param title
+ * the title
+ */
+ public void setTitle(String label);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialog.java
new file mode 100644
index 00000000000..3dd10d27407
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialog.java
@@ -0,0 +1,220 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+
+import java.util.Collections;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * A Dialog used to input a String. The dialog uses a IInputValidator
+ * to check the string, and can display an error message.
+ *
+ * @author Camille Letavernier
+ */
+public class InputDialog extends SelectionDialog {
+
+ /**
+ * The initial value for the string
+ */
+ protected String initialValue;
+
+ /**
+ * The string validator
+ */
+ protected IInputValidator validator;
+
+ /**
+ * The label used to display the error message
+ */
+ protected Label errorLabel;
+
+ /**
+ * The label used to display the error icon
+ */
+ protected Label errorImage;
+
+ /**
+ * The text widget used to input a new string
+ */
+ protected AbstractValueEditor editor;
+
+ /**
+ * The dialog's title
+ */
+ protected String title;
+
+ /**
+ * The label describing the kind of text to input
+ */
+ protected String labelText;
+
+ /**
+ * The content provider used to suggest predefined values to the user
+ */
+ protected IStaticContentProvider contentProvider;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which the dialog will be opened
+ * @param title
+ * The dialog's title
+ * @param initialValue
+ * The dialog's initial value
+ * @param validator
+ * The validator used to check the input string
+ */
+ public InputDialog(Shell parentShell, String title, String label, String initialValue, IInputValidator validator) {
+ super(parentShell);
+ this.initialValue = initialValue;
+ this.validator = validator;
+ this.title = title;
+ this.labelText = label;
+ }
+
+ @Override
+ protected Composite getDialogArea() {
+ return (Composite) super.getDialogArea();
+ }
+
+ @Override
+ public void create() {
+ super.create();
+
+ ((GridLayout) getDialogArea().getLayout()).numColumns = 2;
+
+ errorImage = new Label(getDialogArea(), SWT.NONE);
+ errorImage.setImage(Activator.getDefault().getImage("/icons/error.gif")); //$NON-NLS-1$
+
+ errorLabel = new Label(getDialogArea(), SWT.NONE);
+ errorLabel.setVisible(false);
+
+ Label label = new Label(getDialogArea(), SWT.None);
+ if (labelText != null) {
+ label.setText(labelText);
+ }
+ label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+
+ if (contentProvider != null) {
+ editor = new StringCombo(getDialogArea(), SWT.BORDER);
+ ((StringCombo) editor).setValue(initialValue);
+ ((StringCombo) editor).setContentProvider(contentProvider);
+ } else {
+ editor = new StringEditor(getDialogArea(), SWT.BORDER) {
+
+ // FIXME: The StringEditor (Or one of its superclasses) should be responsible for forwarding this call
+ @Override
+ public void addKeyListener(KeyListener keyListener) {
+ super.text.addKeyListener(keyListener);
+ }
+ };
+
+ ((StringEditor) editor).setValue(initialValue);
+ }
+ // input = new Text(getDialogArea(), SWT.BORDER);
+ // input.setText(initialValue);
+ editor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+
+ editor.addKeyListener(new KeyListener() {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ validate();
+ }
+
+ });
+
+ getShell().setImage(Activator.getDefault().getImage("/icons/papyrus.png")); //$NON-NLS-1$
+
+ if (title != null) {
+ getShell().setText(title);
+ }
+
+ validate();
+ getShell().pack();
+ }
+
+ /**
+ * Validates the current string. If the string isn't valid,
+ * and error message will be displayed.
+ */
+ protected void validate() {
+ if (validator == null) {
+ errorLabel.setVisible(false);
+ errorImage.setVisible(false);
+ getOkButton().setEnabled(true);
+ return;
+ }
+
+ String errorMessage = validator.isValid((String) editor.getValue());
+ if (errorMessage == null) {
+ errorLabel.setVisible(false);
+ errorImage.setVisible(false);
+ getOkButton().setEnabled(true);
+ } else {
+ errorLabel.setText(errorMessage);
+ errorLabel.setVisible(true);
+ errorImage.setVisible(true);
+ getOkButton().setEnabled(false);
+ }
+
+ getDialogArea().layout(true);
+ }
+
+ @Override
+ protected void okPressed() {
+ setResult(Collections.singletonList((String) editor.getValue()));
+ super.okPressed();
+ }
+
+ /**
+ * @return the input text from this dialog, or null
+ * if the dialog has been canceled
+ */
+ public String getText() {
+ Object[] result = getResult();
+ if (result == null || result.length == 0) {
+ return null;
+ }
+ return (String) result[0];
+ }
+
+ /**
+ * Sets a content provider to suggest predefined values to the user
+ *
+ * @param contentProvider
+ */
+ public void setContentProvider(IStaticContentProvider contentProvider) {
+ this.contentProvider = contentProvider;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialogWithLocation.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialogWithLocation.java
new file mode 100644
index 00000000000..72de46c05a4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/InputDialogWithLocation.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * The developper can define the location of this input dialog
+ *
+ * @author vl222926
+ *
+ */
+public class InputDialogWithLocation extends InputDialog {
+
+ /**
+ * the location wanted to display the dialog
+ */
+ private Point location;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @see InputDialog#InputDialog(Shell, String, String, String, IInputValidator)
+ * @param parentShell
+ * @param title
+ * @param label
+ * @param initialValue
+ * @param validator
+ * @param dialogLocation
+ * the location to use for the dialog
+ */
+ public InputDialogWithLocation(Shell parentShell, String title, String label, String initialValue, IInputValidator validator, final Point dialogLocation) {
+ super(parentShell, title, label, initialValue, validator);
+ this.location = dialogLocation;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.InputDialog#create()
+ *
+ */
+ @Override
+ public void create() {
+ super.create();
+ // adapted code from AbstractStyleEditorDialog in nattable plugin
+ if (location != null) {
+ if (location.x < getParentShell().getDisplay().getBounds().x) {
+ location.x = getParentShell().getDisplay().getBounds().x;
+ } else if (location.x + getShell().getBounds().width > getParentShell().getDisplay().getBounds().x + getParentShell().getDisplay().getBounds().width) {
+ location.x = getParentShell().getDisplay().getBounds().x + getParentShell().getDisplay().getBounds().width - getShell().getBounds().width;
+ }
+ if (location.y + getShell().getBounds().height > getParentShell().getDisplay().getBounds().y + getParentShell().getDisplay().getBounds().height) {
+ location.y = getParentShell().getDisplay().getBounds().y + getParentShell().getDisplay().getBounds().height - getShell().getBounds().height;
+ }
+ }
+ getShell().setLocation(location);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerEditor.java
new file mode 100644
index 00000000000..ea6c89d4478
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerEditor.java
@@ -0,0 +1,146 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.validator.IntegerValidator;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Property Editor representing an Integer value as a text box.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class IntegerEditor extends StringEditor {
+
+ /**
+ * The IConverter for converting data from the widget to the model
+ */
+ private IConverter targetToModelConverter;
+
+
+ /**
+ * Constructs an editor for Integer values. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The Text's style
+ */
+ public IntegerEditor(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ * Constructs an editor for Integer values. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The Text's style
+ * @param label
+ * The editor's label
+ */
+ public IntegerEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+
+ targetValidator = new IntegerValidator();
+
+ targetToModelConverter = new IConverter() {
+
+ @Override
+ public Object getToType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Object getFromType() {
+ return String.class;
+ }
+
+ @Override
+ public Integer convert(Object fromObject) {
+ if (fromObject instanceof String) {
+ String newString = ((String) fromObject).replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ Integer i = (Integer) StringToNumberConverter.toInteger(false).convert(newString);
+ return i;
+ } catch (Exception ex) {
+
+ }
+
+ }
+
+ return null;
+ }
+ };
+
+ IConverter integerToString = new IConverter() {
+
+ @Override
+ public Object getToType() {
+ return String.class;
+ }
+
+ @Override
+ public Object getFromType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Object convert(Object fromObject) {
+
+ if (fromObject instanceof Integer) {
+ return Integer.toString((Integer) fromObject);
+ }
+ errorBinding = true;
+ return ""; //$NON-NLS-1$
+ }
+
+ };
+ setValidateOnDelay(true);
+ setConverters(targetToModelConverter, integerToString);
+ setTargetAfterGetValidator(targetValidator);
+
+ }
+
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Integer.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer getValue() {
+ try {
+
+ return (Integer) targetToModelConverter.convert(super.getValue());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerMask.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerMask.java
new file mode 100644
index 00000000000..de609cd4b74
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerMask.java
@@ -0,0 +1,216 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+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;
+
+public class IntegerMask extends AbstractValueEditor implements SelectionListener, IChangeListener, DisposeListener {
+
+ private Button[] checkboxes;
+
+ private int currentValue;
+
+ private final Composite checkboxContainer;
+
+ private boolean refreshCheckboxes = true;
+
+ public IntegerMask(final Composite parent, final int style) {
+ super(parent, style);
+ checkboxContainer = new Composite(this, style);
+ checkboxContainer.setLayoutData(getDefaultLayoutData());
+ checkboxContainer.setLayout(new GridLayout(2, true));
+ checkboxContainer.addDisposeListener(this);
+ }
+
+ @Override
+ protected GridData getLabelLayoutData() {
+ GridData data = super.getLabelLayoutData();
+ data.verticalAlignment = SWT.BEGINNING;
+ return data;
+ }
+
+ @Override
+ public Object getValue() {
+ int totalValue = 0;
+ for (Button button : checkboxes) {
+ int value = (Integer) button.getData("IntValue"); //$NON-NLS-1$
+ if (button.getSelection()) {
+ totalValue |= value;
+ }
+ }
+ return totalValue;
+ }
+
+ @Override
+ public void dispose() {
+ if (modelProperty != null) {
+ modelProperty.removeChangeListener(this);
+ }
+ super.dispose();
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Integer.class;
+ }
+
+ @Override
+ public void setReadOnly(final boolean readOnly) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setMasks(final String[] values) {
+ Map<Integer, String> masks = new HashMap<Integer, String>();
+ int intValue = 1;
+ for (String value : values) {
+ masks.put(intValue, value);
+ intValue <<= 1;
+ }
+ setMasks(masks);
+ }
+
+ public void setMasks(final Map<Integer, String> values) {
+ if (values.size() > 32) {
+ StringLabel label = new StringLabel(checkboxContainer, SWT.NONE);
+ label.getValueLabel().setImage(Activator.getDefault().getImage("/icons/error.gif")); //$NON-NLS-1$
+ label.getValueLabel().setText(Messages.IntegerMask_ErrorTooManyValues);
+ checkboxes = new Button[0];
+ } else {
+ if (checkboxes != null) {
+ disposeCheckboxes();
+ }
+
+ checkboxes = new Button[values.size()];
+
+ int i = 0;
+ for (Entry<Integer, String> mask : values.entrySet()) {
+ int intValue = mask.getKey();
+ String value = mask.getValue();
+ checkboxes[i] = new Button(checkboxContainer, SWT.CHECK);
+ checkboxes[i].setText(value);
+ checkboxes[i].setData("IntValue", intValue); //$NON-NLS-1$
+ checkboxes[i].addSelectionListener(this);
+ i++;
+ }
+ }
+ }
+
+ protected void disposeCheckboxes() {
+ for (Button button : checkboxes) {
+ button.removeSelectionListener(this);
+ button.dispose();
+ }
+ }
+
+ public void setNumColumns(final int numColumns) {
+ ((GridLayout) checkboxContainer.getLayout()).numColumns = numColumns;
+ checkboxContainer.layout();
+ layout();
+ }
+
+ @Override
+ public void doBinding() {
+ // We don't do a real databinding here
+ modelProperty.addChangeListener(this);
+
+ refreshCheckboxes();
+ }
+
+ protected void refreshCheckboxes() {
+ if (!refreshCheckboxes) {
+ return;
+ }
+
+ int totalValue = getCurrentValue();
+ for (Button button : checkboxes) {
+ int value = (Integer) button.getData("IntValue"); //$NON-NLS-1$
+ button.setSelection((totalValue & value) != 0);
+ }
+ }
+
+ @Override
+ public void setToolTipText(final String text) {
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ Button button = (Button) e.widget;
+ int value = (Integer) button.getData("IntValue"); //$NON-NLS-1$
+ int totalValue = getCurrentValue();
+ if (button.getSelection()) {
+ totalValue |= value;
+ } else {
+ totalValue &= ~value;
+ }
+ setCurrentValue(totalValue);
+ }
+
+ protected void setCurrentValue(final int value) {
+ if (modelProperty != null) {
+ refreshCheckboxes = false;
+ modelProperty.setValue(value);
+ refreshCheckboxes = true;
+ }
+ currentValue = value;
+
+ commit();
+ }
+
+ protected Integer getCurrentValue() {
+ if (modelProperty != null) {
+ Object value = modelProperty.getValue();
+ return value == null ? 0 : (Integer) value;
+ } else {
+ return currentValue;
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(final SelectionEvent e) {
+ // Nothing
+ }
+
+ public int getNumColumns() {
+ return ((GridLayout) checkboxContainer.getLayout()).numColumns;
+ }
+
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ refreshCheckboxes();
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerSpinner.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerSpinner.java
new file mode 100644
index 00000000000..defe38a6ce7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IntegerSpinner.java
@@ -0,0 +1,325 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Spinner;
+
+/**
+ * A widget for editing Integer values with a SWT Spinner
+ *
+ * @author Camille Letavernier
+ *
+ * @see Spinner
+ */
+public class IntegerSpinner extends AbstractValueEditor implements KeyListener, ModifyListener {
+
+ /**
+ * The SWT Spinner
+ */
+ protected Spinner spinner;
+
+ /**
+ * The String to Integer converter
+ */
+ protected IConverter targetToModelConverter;
+
+
+ private Timer timer;
+
+ private TimerTask changeColorTask;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which the editor will be created
+ * @param style
+ * The SWT style to apply
+ */
+ public IntegerSpinner(Composite parent, int style) {
+ super(parent, style);
+ spinner = createSpinner();
+
+ setWidgetObservable(new AbstractObservableValue() {
+
+ @Override
+ public Object getValueType() {
+ return Integer.class;
+ }
+
+ @Override
+ protected Integer doGetValue() {
+ return (Integer) targetToModelConverter.convert(spinner.getText());
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ spinner.setSelection((Integer) value);
+ }
+
+ });
+
+ spinner.addKeyListener(this);
+ spinner.addModifyListener(this);
+ setCommitOnFocusLost(spinner);
+
+ GridData gridData = getDefaultLayoutData();
+ spinner.setLayoutData(gridData);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ targetToModelConverter = StringToNumberConverter.toInteger(false);
+ controlDecoration = new ControlDecoration(spinner, SWT.LEFT | SWT.LEFT);
+ }
+
+ /**
+ * Creates the Spinner
+ *
+ * @return the Spinner
+ */
+ protected Spinner createSpinner() {
+ return new Spinner(this, factory.getBorderStyle());
+ }
+
+ @Override
+ public void doBinding() {
+
+ spinner.addFocusListener(new FocusListener() {
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ binding.updateTargetToModel();
+ }
+
+ });
+
+ super.doBinding();
+ }
+
+ @Override
+ public Object getValue() {
+ String value = spinner.getText();
+ return targetToModelConverter.convert(value);
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Integer.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ spinner.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !spinner.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ spinner.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ /**
+ * Sets the minimum value for the spinner
+ *
+ * @param minimum
+ * @see Spinner#setMinimum(int)
+ */
+ public void setMinimum(int minimum) {
+ spinner.setMinimum(minimum);
+ }
+
+ /**
+ * Sets the maximum value for the spinner
+ *
+ * @param maximum
+ * @see Spinner#setMaximum(int)
+ */
+ public void setMaximum(int maximum) {
+ spinner.setMaximum(maximum);
+ }
+
+ /**
+ * Sets the increment value for the spinner
+ *
+ * @param increment
+ * @see Spinner#setIncrement(int)
+ */
+ public void setIncrement(int increment) {
+ spinner.setIncrement(increment);
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+ notifyChange();
+ }
+
+ }
+
+ protected void notifyChange() {
+ spinner.notifyListeners(SWT.FocusOut, new Event());
+ commit();
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+ }
+
+ private void cancelCurrentTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ }
+
+ @Override
+ public void changeColorField() {
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ IntegerSpinner.this.getDisplay().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (!spinner.isDisposed()) {
+ spinner.setBackground(DEFAULT);
+ spinner.update();
+ }
+ }
+
+
+ });
+ }
+ };
+ if (errorBinding) {
+ spinner.setBackground(ERROR);
+ spinner.update();
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ spinner.setBackground(VALID);
+ spinner.update();
+ break;
+ case IStatus.ERROR:
+ spinner.setBackground(ERROR);
+ spinner.update();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ changeColorTask = null;
+ }
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ super.dispose();
+ }
+
+ /**
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ *
+ * @param e
+ */
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ if (modelProperty == null) {
+ return;
+ }
+
+ if (modelProperty.getValue() != null) {
+ if (!isReadOnly() && !modelProperty.getValue().toString().equals(spinner.getText())) {
+ spinner.setBackground(EDIT);
+ } else {
+ spinner.setBackground(DEFAULT);
+ }
+ } else {
+ if (spinner.getText().equals("")) {
+ spinner.setBackground(DEFAULT);
+ } else {
+ spinner.setBackground(EDIT);
+ }
+ }
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/LongEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/LongEditor.java
new file mode 100644
index 00000000000..b11e57372e9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/LongEditor.java
@@ -0,0 +1,53 @@
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Locale;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.conversion.NumberToStringConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.swt.widgets.Composite;
+
+import com.ibm.icu.text.NumberFormat;
+
+public class LongEditor extends StringEditor {
+
+ private IConverter targetToModelConverter;
+
+ /**
+ *
+ * Constructs an Editor for a Long value. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which the editor is created
+ * @param style
+ * The Text's style
+ */
+ public LongEditor(Composite parent, int style) {
+ super(parent, style);
+
+ targetToModelConverter = StringToNumberConverter.toLong(NumberFormat.getInstance(Locale.ENGLISH), true);
+ setConverters(targetToModelConverter, NumberToStringConverter.fromLong(NumberFormat.getInstance(Locale.ENGLISH), true));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Long.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Long getValue() {
+ try {
+ return (Long) targetToModelConverter.convert(super.getValue());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleDoubleEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleDoubleEditor.java
new file mode 100644
index 00000000000..bae688415de
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleDoubleEditor.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+
+import org.eclipse.papyrus.infra.widgets.selectors.RealSelector;
+import org.eclipse.swt.widgets.Composite;
+
+
+public class MultipleDoubleEditor extends MultipleStringEditor {
+
+ /**
+ * Constructs an Editor for multiple double values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ */
+ public MultipleDoubleEditor(Composite parent, int style) {
+ super(parent, style, new RealSelector());
+ }
+
+ /**
+ * Constructs an Editor for multiple double values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param label
+ * The editor's label
+ */
+ public MultipleDoubleEditor(Composite parent, int style, String label) {
+ super(parent, style, new RealSelector(), label);
+ }
+
+ /**
+ * Constructs an Editor for multiple double values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param ordered
+ * Indicates if the values should be ordered. If true, the up/down controls will be activated
+ * @param unique
+ * Indicates if the values should be unique.
+ * @param label
+ * The editor's label
+ */
+ public MultipleDoubleEditor(Composite parent, int style, boolean ordered, boolean unique, String label) {
+ super(parent, style, new RealSelector(), ordered, unique, label);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleIntegerEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleIntegerEditor.java
new file mode 100644
index 00000000000..4b3604e4af6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleIntegerEditor.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.infra.widgets.editors;
+
+import org.eclipse.papyrus.infra.widgets.selectors.IntegerSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An editor for multivalued Integer attributes
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class MultipleIntegerEditor extends MultipleStringEditor {
+
+ /**
+ * Constructs an Editor for multiple Integer values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ */
+ public MultipleIntegerEditor(Composite parent, int style) {
+ super(parent, style, new IntegerSelector());
+ }
+
+ /**
+ * Constructs an Editor for multiple Integer values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param label
+ * The editor's label
+ */
+ public MultipleIntegerEditor(Composite parent, int style, String label) {
+ super(parent, style, new IntegerSelector(), label);
+ }
+
+ /**
+ * Constructs an Editor for multiple Integer values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param ordered
+ * Indicates if the values should be ordered. If true, the up/down controls will be activated
+ * @param unique
+ * Indicates if the values should be unique.
+ * @param label
+ * The editor's label
+ */
+ public MultipleIntegerEditor(Composite parent, int style, boolean ordered, boolean unique, String label) {
+ super(parent, style, new IntegerSelector(), ordered, unique, label);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleReferenceEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleReferenceEditor.java
new file mode 100644
index 00000000000..7330d044179
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleReferenceEditor.java
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.providers.EmptyContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.WrappedLabelProvider;
+import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An editor for multivalued references. This editor should be used when
+ * there is enough vertical space available. If the vertical space is limited,
+ * CompactMultipleReferenceEditor should be used instead.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class MultipleReferenceEditor extends MultipleValueEditor {
+
+ /**
+ * The element selector for the available values
+ */
+ protected ReferenceSelector selector;
+
+ protected IStaticContentProvider contentProvider;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor is created
+ * @param style
+ * The style for this editor's list
+ * @param ordered
+ * True if the list should be ordered
+ * @param unique
+ * True if the list values should be unique
+ * @param label
+ * The label for this editor
+ */
+ public MultipleReferenceEditor(Composite parent, int style, boolean ordered, boolean unique, String label) {
+ super(parent, style, new ReferenceSelector(unique), ordered, unique, label);
+ this.selector = (ReferenceSelector) super.selector;
+ // Default providers
+ setProviders(EmptyContentProvider.instance, new WrappedLabelProvider());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor is created
+ * @param style
+ * The style for this editor's list
+ * @param label
+ * The label for this editor
+ */
+ public MultipleReferenceEditor(Composite parent, int style, String label) {
+ this(parent, style, false, false, label);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor is created
+ * @param style
+ * The style for this editor's list
+ */
+ public MultipleReferenceEditor(Composite parent, int style) {
+ this(parent, style, false, false, null);
+ }
+
+ /**
+ * Sets the Content and Label providers for this editor
+ *
+ * @param contentProvider
+ * The content provider describing the elements that can be selected
+ * @param labelProvider
+ * The label provider for the elements
+ */
+ public void setProviders(IStaticContentProvider contentProvider, ILabelProvider labelProvider) {
+ Assert.isNotNull(contentProvider, "The content provider should be defined"); //$NON-NLS-1$
+
+ this.contentProvider = contentProvider;
+
+ selector.setContentProvider(contentProvider);
+
+ if (labelProvider != null) {
+ selector.setLabelProvider(labelProvider);
+ super.setLabelProvider(labelProvider);
+ }
+ }
+
+ @Override
+ public void setUnique(boolean unique) {
+ selector.setUnique(unique);
+ super.setUnique(unique);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringEditor.java
new file mode 100644
index 00000000000..ade19dcc579
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringEditor.java
@@ -0,0 +1,181 @@
+/*****************************************************************************
+ * 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.infra.widgets.editors;
+
+import org.eclipse.papyrus.infra.widgets.creation.StringEditionFactory;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.selectors.StandardSelector;
+import org.eclipse.papyrus.infra.widgets.selectors.StringSelector;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * An editor for multivalued String attributes
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class MultipleStringEditor extends MultipleValueEditor {
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ */
+ public MultipleStringEditor(Composite parent, int style) {
+ super(parent, style, new StringSelector());
+ init();
+ }
+
+ public MultipleStringEditor(Composite parent, int style, boolean multiline) {
+ super(parent, style, new StringSelector(multiline));
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param ordered
+ * Indicates if the values should be ordered. If true, the up/down controls will be activated
+ * @param unique
+ * Indicates if the values should be unique.
+ */
+ public MultipleStringEditor(Composite parent, int style, boolean ordered, boolean unique) {
+ super(parent, style, new StringSelector(), ordered, unique, null);
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param ordered
+ * Indicates if the values should be ordered. If true, the up/down controls will be activated
+ * @param unique
+ * Indicates if the values should be unique.
+ * @param label
+ * The editor's label
+ */
+ public MultipleStringEditor(Composite parent, int style, boolean ordered, boolean unique, String label) {
+ super(parent, style, new StringSelector(), ordered, unique, label);
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param selector
+ * The Element selector for the dialog's left-pane. Used to select values or enter new ones.
+ * @param ordered
+ * Indicates if the values should be ordered. If true, the up/down controls will be activated
+ * @param unique
+ * Indicates if the values should be unique.
+ * @param label
+ * The editor's label
+ */
+ public MultipleStringEditor(Composite parent, int style, IElementSelector selector, boolean ordered, boolean unique, String label) {
+ super(parent, style, selector, ordered, unique, label);
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple Integer values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param selector
+ * The Element selector for the dialog's left-pane. Used to select values or enter new ones.
+ */
+ public MultipleStringEditor(Composite parent, int style, IElementSelector selector) {
+ super(parent, style, selector);
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param selector
+ * The Element selector for the dialog's left-pane. Used to select values or enter new ones.
+ * @param label
+ * The editor's label
+ */
+ public MultipleStringEditor(Composite parent, int style, IElementSelector selector, String label) {
+ super(parent, style, selector, label);
+ init();
+ }
+
+ /**
+ * Constructs an Editor for multiple String values
+ * The widget is a List, with controls to move values up/down, add values
+ * and remove values.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The List's style
+ * @param label
+ * The editor's label
+ */
+ public MultipleStringEditor(Composite parent, int style, String label) {
+ super(parent, style, new StringSelector(), label);
+ init();
+ }
+
+ private void init() {
+ setFactory(new StringEditionFactory());
+ }
+
+ public void setContentProvider(final IStaticContentProvider provider) {
+ IElementSelector selector = new StandardSelector(StringCombo.class) {
+
+ @Override
+ public void createControls(Composite parent) {
+ super.createControls(parent);
+ ((StringCombo) editor).setProviders(provider, null);
+ }
+ };
+ setSelector(selector);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringFileEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringFileEditor.java
new file mode 100644
index 00000000000..f69aa41b8ca
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleStringFileEditor.java
@@ -0,0 +1,228 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
+import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider;
+import org.eclipse.papyrus.infra.widgets.selectors.NullSelector;
+import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector;
+import org.eclipse.papyrus.infra.widgets.util.FileUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+
+/**
+ * A Widget for editing multi-valued Strings with File paths
+ * The file paths may be absolute (FileSystem paths) or relative to the workspace (Workspace paths)
+ *
+ * @author Camille Letavernier
+ */
+public class MultipleStringFileEditor extends MultipleValueEditor {
+
+ protected boolean allowBrowseWorkspace = true;
+
+ protected boolean allowBrowseFileSystem = true;
+
+ protected Button browseFileSystem;
+
+ protected Button browseWorkspace;
+
+ protected final List<String> filterNames;
+
+ protected final List<String> filterExtensions;
+
+ public static final String browseWorkspaceIcon = "icons/browse-workspace_12x12.png"; //$NON-NLS-1$
+
+ public static final String browseFileSystemIcon = "icons/browse-filesystem_12x12.png"; //$NON-NLS-1$
+
+ public MultipleStringFileEditor(Composite parent, int style) {
+ super(parent, style, NullSelector.instance);
+ setDirectCreation(true);
+
+ filterNames = new LinkedList<String>();
+ filterExtensions = new LinkedList<String>();
+ }
+
+ @Override
+ protected void createListControls() {
+ super.createListControls();
+ add.dispose();
+ edit.dispose();
+
+ browseFileSystem = createButton(Activator.getDefault().getImageFromPlugin(browseFileSystemIcon), Messages.MultipleStringFileEditor_0);
+ browseWorkspace = createButton(Activator.getDefault().getImageFromPlugin(browseWorkspaceIcon), Messages.MultipleStringFileEditor_1);
+
+ browseWorkspace.moveAbove(remove);
+ browseFileSystem.moveAbove(remove);
+ }
+
+ @Override
+ public void setDirectCreation(boolean directCreation) {
+ super.setDirectCreation(true); // Always true
+ }
+
+ @Override
+ protected void updateControls() {
+ remove.setEnabled(!readOnly);
+ up.setEnabled(ordered && !readOnly);
+ down.setEnabled(ordered && !readOnly);
+
+ browseWorkspace.setEnabled(allowBrowseWorkspace && !readOnly);
+ browseFileSystem.setEnabled(allowBrowseFileSystem && !readOnly);
+ }
+
+ public void allowBrowseWorkspace(boolean allowBrowseWorkspace) {
+ this.allowBrowseWorkspace = allowBrowseWorkspace;
+ }
+
+ public void allowBrowseFileSystem(boolean allowBrowseFileSystem) {
+ this.allowBrowseFileSystem = allowBrowseFileSystem;
+ }
+
+ /**
+ * Handle events occuring on controls
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ super.widgetSelected(e);
+ if (e.widget == browseFileSystem) {
+ browseFileSystem();
+ } else if (e.widget == browseWorkspace) {
+ browseWorkspace();
+ }
+ }
+
+ protected void browseFileSystem() {
+ // File file = FileUtil.getFile(text.getText());
+
+ FileDialog dialog = new FileDialog(getShell(), SWT.MULTI | SWT.OPEN);
+ dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()]));
+ dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()]));
+ if (dialog.open() != null) {
+ List<String> filePathList = new ArrayList<String>(modelProperty.size() + dialog.getFileNames().length);
+ filePathList.addAll(modelProperty);
+
+ for (String fileName : dialog.getFileNames()) {
+ filePathList.add(dialog.getFilterPath() + File.separator + fileName);
+ }
+
+ modelProperty.clear();
+ modelProperty.addAll(filePathList);
+ commit();
+ }
+ }
+
+ protected void browseWorkspace() {
+ LabelProviderService labelProviderService = new LabelProviderServiceImpl();
+ try {
+ labelProviderService.startService();
+ } catch (ServiceException ex) {
+ Activator.log.error(ex);
+ }
+
+ ILabelProvider labelProvider = labelProviderService.getLabelProvider();
+
+ ReferenceSelector selector = new ReferenceSelector();
+ selector.setLabelProvider(labelProvider);
+
+
+ // Prepare the WorkspaceContentProvider and use the right filters
+ WorkspaceContentProvider contentProvider = new WorkspaceContentProvider();
+
+ contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); // Reset the default filters
+ for (int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) {
+ contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i));
+ }
+
+ selector.setContentProvider(contentProvider);
+
+
+ MultipleValueSelectorDialog dialog = new MultipleValueSelectorDialog(getShell(), selector);
+ if (labelText != null) {
+ dialog.setTitle(labelText);
+ }
+
+ dialog.setLabelProvider(labelProvider);
+
+ dialog.setOrdered(true);
+ dialog.setUnique(true);
+ selector.setUnique(true);
+
+ int code = dialog.open();
+ if (code == Window.OK) {
+ Object[] result = dialog.getResult();
+ if (result.length > 0) {
+ List<String> filePathResult = new ArrayList<String>(result.length + modelProperty.size());
+ filePathResult.addAll(modelProperty);
+ for (Object file : result) {
+ if (file instanceof IFile) {
+ filePathResult.add(FileUtil.getPath((IFile) file, false));
+ }
+ }
+ modelProperty.clear();
+ modelProperty.addAll(filePathResult);
+ commit();
+ }
+ }
+ }
+
+ public void setFilters(String[] filterExtensions, String[] filterNames) {
+ if (filterExtensions.length != filterNames.length) {
+ // This is a simple warning. Only valid filters will be retained.
+ Activator.log.warn(Messages.MultipleStringFileEditor_2);
+ }
+
+ setFilterNames(getFilterLabels(filterNames, filterExtensions));
+ setFilterExtensions(filterExtensions);
+ }
+
+ protected String[] getFilterLabels(String[] filterNames, String[] filterExtensions) {
+ int size = Math.min(filterNames.length, filterExtensions.length);
+ String[] filters = new String[size];
+ for (int i = 0; i < size; i++) {
+ filters[i] = filterNames[i] + " (" + filterExtensions[i] + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return filters;
+ }
+
+ public void setFilterExtensions(String[] filterExtensions) {
+ this.filterExtensions.clear();
+ this.filterExtensions.addAll(Arrays.asList(filterExtensions));
+ }
+
+ public void setFilterNames(String[] filterNames) {
+ this.filterNames.clear();
+ this.filterNames.addAll(Arrays.asList(filterNames));
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java
new file mode 100644
index 00000000000..26dce0a5897
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java
@@ -0,0 +1,725 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ * Christian W. Damus - bug 399859
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.TreeCollectionContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.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.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * An editor for multivalued fields.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class MultipleValueEditor extends AbstractListEditor implements SelectionListener, IChangeListener, DisposeListener {
+
+ public static final int MANY = -1;
+
+ /**
+ * The viewer displaying the current values from
+ * the model
+ */
+ protected TreeViewer treeViewer;
+
+ /**
+ * The tree associated to the viewer
+ */
+ protected Tree tree;
+
+ /**
+ * A Composite containing the different control buttons
+ * (Add, remove, ...)
+ */
+ protected Composite controlsSection;
+
+ /**
+ * The Add control
+ */
+ protected Button add;
+
+ /**
+ * The Remove control
+ */
+ protected Button remove;
+
+ /**
+ * The Up control
+ */
+ protected Button up;
+
+ /**
+ * The Down control
+ */
+ protected Button down;
+
+ /**
+ * The edit control
+ */
+ protected Button edit;
+
+ /**
+ * The element selector for this editor's dialog
+ */
+ protected IElementSelector selector;
+
+ /**
+ * Indicates whether the underlying is ordered
+ */
+ protected boolean ordered;
+
+ /**
+ * Indicates whether the underlying contains unique values
+ */
+ protected boolean unique;
+
+ /**
+ * The factory for creating and editing values from
+ * this editor
+ */
+ protected ReferenceValueFactory referenceFactory;
+
+ /**
+ * Indicates if this editor is readOnly
+ */
+ protected boolean readOnly;
+
+ private boolean directCreation;
+
+ /**
+ * Indicates the maximum number of values selected.
+ */
+ protected int upperBound;
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this Editor should be displayed
+ * @param style
+ * This editor's tree style
+ * @param selector
+ * The element selector for this editor's dialog
+ * @param ordered
+ * Specify if the observed collection is ordered. If true, Up and Down controls are displayed.
+ * @param unique
+ * Specify if the observed collection values are unique.
+ * @param label
+ * The label for this editor. If null, the label isn't created.
+ */
+ public MultipleValueEditor(Composite parent, int style, IElementSelector selector, boolean ordered, boolean unique, String label) {
+ this(parent, style, selector, ordered, unique, label, MANY);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this Editor should be displayed
+ * @param style
+ * This editor's tree style
+ * @param selector
+ * The element selector for this editor's dialog
+ * @param ordered
+ * Specify if the observed collection is ordered. If true, Up and Down controls are displayed.
+ * @param unique
+ * Specify if the observed collection values are unique.
+ * @param label
+ * The label for this editor. If null, the label isn't created.
+ * @param upperBound
+ * The maximum number of values that must appear.
+ */
+ public MultipleValueEditor(Composite parent, int style, IElementSelector selector, boolean ordered, boolean unique, String label, int upperBound) {
+ super(parent, label);
+ Assert.isNotNull(selector, "The Element Selector must be specified for a MultipleValueEditor"); //$NON-NLS-1$
+
+ setLayout(new GridLayout(label == null ? 1 : 2, false));
+
+ controlsSection = new Composite(this, SWT.NONE);
+ controlsSection.setLayout(new FillLayout());
+ controlsSection.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
+
+ tree = new Tree(this, style | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
+ GridData treeData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ treeData.horizontalSpan = 2;
+ treeData.minimumHeight = 80;
+ tree.setLayoutData(treeData);
+
+ tree.addSelectionListener(this);
+
+ treeViewer = new TreeViewer(tree);
+ treeViewer.setContentProvider(TreeCollectionContentProvider.instance);
+
+ createListControls();
+
+ this.selector = selector;
+
+ setLabelProvider(new LabelProvider());
+ setUpperBound(upperBound);
+ this.ordered = ordered;
+ this.unique = unique;
+ updateControls();
+ }
+
+ /**
+ * Creates the dialog for this editor
+ *
+ * @param parent
+ * The Composite in which the dialog should be displayed
+ * @param selector
+ * The element selector for this dialog
+ * @param ordered
+ * Specify if the observed collection is ordered. If true, Up and Down controls are displayed.
+ * @param unique
+ * Specify if the observed collection values are unique.
+ * @param label
+ * The editor's label.
+ * @return The new dialog for this editor
+ */
+ protected MultipleValueSelectorDialog createMultipleValueSelectorDialog(Composite parent, IElementSelector selector, boolean ordered, boolean unique, String label) {
+ return new MultipleValueSelectorDialog(parent.getShell(), selector, label, unique, ordered);
+ }
+
+ @Override
+ protected GridData getLabelLayoutData() {
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ return data;
+ }
+
+ public void setSelector(IElementSelector selector) {
+ this.selector = selector;
+ }
+
+ protected void updateControls() {
+
+ boolean enableAddAction = true;
+ if (directCreation) {
+ if (referenceFactory == null || !referenceFactory.canCreateObject()) {
+ enableAddAction = false;
+ }
+ }
+
+ add.setEnabled(!readOnly && enableAddAction);
+ remove.setEnabled(!readOnly);
+ up.setEnabled(ordered && !readOnly);
+ down.setEnabled(ordered && !readOnly);
+
+ if (edit != null) {
+ edit.setEnabled(this.referenceFactory != null && referenceFactory.canEdit() && !readOnly);
+ }
+
+ if (modelProperty != null && this.upperBound != MANY) {
+ if (modelProperty.size() >= this.upperBound) {
+ add.setEnabled(false);
+ }
+ }
+
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this Editor should be displayed
+ * @param style
+ * This editor's tree style
+ * @param selector
+ * The element selector for this editor's dialog
+ * @param ordered
+ * Specify if the observed collection is ordered. If true, Up and Down controls are displayed
+ */
+ public MultipleValueEditor(Composite parent, int style, IElementSelector selector, boolean ordered) {
+ this(parent, style, selector, ordered, false, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this Editor should be displayed
+ * @param style
+ * This editor's tree style
+ * @param selector
+ * The element selector for this editor's dialog
+ */
+ public MultipleValueEditor(Composite parent, int style, IElementSelector selector) {
+ this(parent, style, selector, false, false, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this Editor should be displayed
+ * @param style
+ * This editor's tree style
+ * @param selector
+ * The element selector for this editor's dialog
+ * @param label
+ * The label for this Editor
+ */
+ public MultipleValueEditor(Composite parent, int style, IElementSelector selector, String label) {
+ this(parent, style, selector, false, false, label);
+ }
+
+ /**
+ * Sets the label provider for this editor
+ *
+ * @param labelProvider
+ * The label provider for this editor
+ */
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {
+ treeViewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doBinding() {
+ // We don't do a real Databinding in this case
+ treeViewer.setInput(modelProperty);
+ modelProperty.addChangeListener(this);
+ }
+
+ /**
+ * @param ordered
+ */
+ public void setOrdered(boolean ordered) {
+ this.ordered = ordered;
+
+ updateControls();
+ }
+
+ /**
+ * @param unique
+ */
+ public void setUnique(boolean unique) {
+ this.unique = unique;
+
+ updateControls();
+ }
+
+ /**
+ * Creates the Add/Remove controls,
+ * and the Up/Down controls if the collection is ordered
+ *
+ * @param ordered
+ */
+ protected void createListControls() {
+ up = createButton(Activator.getDefault().getImage("/icons/Up_12x12.gif"), Messages.MultipleValueEditor_MoveSelectedElementsUp); //$NON-NLS-1$
+ down = createButton(Activator.getDefault().getImage("/icons/Down_12x12.gif"), Messages.MultipleValueEditor_MoveSelectedElementsDown); //$NON-NLS-1$
+ add = createButton(Activator.getDefault().getImage("/icons/Add_12x12.gif"), Messages.MultipleValueEditor_AddElements); //$NON-NLS-1$
+ remove = createButton(Activator.getDefault().getImage("/icons/Delete_12x12.gif"), Messages.MultipleValueEditor_RemoveSelectedElements); //$NON-NLS-1$
+ edit = createButton(Activator.getDefault().getImage("/icons/Edit_12x12.gif"), Messages.MultipleValueEditor_EditSelectedValue); //$NON-NLS-1$
+ }
+
+ protected Button createButton(Image image, String toolTipText) {
+ Button button = new Button(controlsSection, SWT.PUSH);
+ button.setImage(image);
+ button.addSelectionListener(this);
+ button.setToolTipText(toolTipText);
+ return button;
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Collection.class;
+ }
+
+ /**
+ * Handle events occuring on controls
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == null) {
+ return;
+ }
+ if (e.widget == add) {
+ if (this.upperBound == MANY || modelProperty.size() < this.upperBound) {
+ addAction();
+ }
+ } else if (e.widget == remove) {
+ removeAction();
+ } else if (e.widget == up) {
+ upAction();
+ } else if (e.widget == down) {
+ downAction();
+ } else if (e.widget == edit) {
+ editAction();
+ }
+
+ updateBoutons();
+ }
+
+ /**
+ * Handle add Action
+ */
+ protected void addAction() {
+ final Object context = getContextElement();
+
+ if (directCreation) {
+ if (referenceFactory != null && referenceFactory.canCreateObject()) {
+ getOperationExecutor(context).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object newElement = referenceFactory.createObject(MultipleValueEditor.this, context);
+ if (newElement != null) {
+ modelProperty.add(newElement);
+ commit();
+ }
+ }
+ }, NLS.bind(Messages.MultipleValueEditor_addOperation, labelText));
+ }
+
+ return;
+ }
+
+ getOperationExecutor(context).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ String dialogLabel = label == null ? null : label.getText();
+ MultipleValueSelectorDialog dialog = createMultipleValueSelectorDialog(getParent(), selector, ordered, unique, dialogLabel);
+ dialog.setLabelProvider((ILabelProvider) treeViewer.getLabelProvider());
+ dialog.setFactory(referenceFactory);
+ dialog.setUpperBound(upperBound);
+ dialog.setContextElement(context);
+
+ if (modelProperty != null) {
+ dialog.setInitialSelections(modelProperty.toArray());
+ } else {
+ dialog.setInitialSelections(new Object[0]);
+ }
+
+ int returnCode = dialog.open();
+ if (returnCode == Window.CANCEL) {
+ // Clear out the element selector in case we open this dialog again
+ selector.clearTemporaryElements();
+
+ // Roll back whatever has been done, so far
+ throw new OperationCanceledException();
+ }
+
+ modelProperty.clear();
+
+ Object[] result = dialog.getResult();
+ if (result == null) {
+ return;
+ }
+
+ modelProperty.addAll(Arrays.asList(result));
+
+ commit();
+ }
+ }, NLS.bind(Messages.MultipleValueEditor_addOperation, labelText));
+ }
+
+ @Override
+ protected void commit() {
+ super.commit();
+ if (!isDisposed()) {
+ treeViewer.refresh();
+ }
+ }
+
+ /**
+ * Handle remove Action
+ */
+ protected void removeAction() {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+ for (Object value : selection.toArray()) {
+ modelProperty.remove(value);
+ }
+ treeViewer.setSelection(null);
+
+ commit();
+ }
+
+ /**
+ * Handle up Action
+ */
+ protected void upAction() {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+ for (Object o : selection.toArray()) {
+ int oldIndex = modelProperty.indexOf(o);
+ if (oldIndex > 0) {
+ modelProperty.move(oldIndex, oldIndex - 1);
+ }
+ }
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ treeViewer.setSelection(selectionCopy);
+
+ commit();
+ }
+
+ /**
+ * Handle down Action
+ */
+ protected void downAction() {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+
+ int maxIndex = modelProperty.size() - 1;
+
+ Object[] selectionArray = selection.toArray();
+ for (int i = selectionArray.length - 1; i >= 0; i--) {
+ Object o = selectionArray[i];
+ int oldIndex = modelProperty.indexOf(o);
+ if (oldIndex < maxIndex) {
+ modelProperty.move(oldIndex, oldIndex + 1);
+ }
+ }
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ treeViewer.setSelection(selectionCopy);
+
+ commit();
+ }
+
+ /**
+ * Handle edit Action
+ */
+ protected void editAction() {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+
+ if (selection.size() != 1) {
+ return;
+ }
+
+ TreeItem selectedItem = treeViewer.getTree().getSelection()[0];
+ Tree parentTree = selectedItem.getParent();
+
+ final int index = parentTree.indexOf(selectedItem);
+ final Object currentValue = selection.getFirstElement();
+
+ getOperationExecutor(currentValue).execute(new Runnable() {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ Object newValue = referenceFactory.edit(MultipleValueEditor.this.edit, currentValue);
+
+ if (newValue != currentValue && newValue != null) {
+ modelProperty.remove(index);
+ modelProperty.add(index, newValue);
+
+ // commit(); // The commit only occurs in the case where we modify the list (We don't commit direct edition on objects)
+ }
+
+ commit();
+ }
+ }, NLS.bind(Messages.MultipleValueEditor_editOperation, labelText));
+ }
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this editor. The {@link ReferenceValueFactory} is used to create
+ * new instances and edit existing ones.
+ *
+ * @param factory
+ * The {@link ReferenceValueFactory} to be used by this editor
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.referenceFactory = factory;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ if ((e.widget == tree) && (edit != null) && edit.isEnabled()) {
+ editAction();
+ }
+ }
+
+ /**
+ * Gets the tree viewer associated to this editor
+ *
+ * @return the tree viewer associated to this editor
+ */
+ public TreeViewer getViewer() {
+ return treeViewer;
+ }
+
+ /**
+ * Refreshes the viewer when a change occurs on the ObservableList
+ * TODO : Problem : a change occurring on an element of the list is not sent here
+ * TODO : When undoing a command, the change event is not received (Although it modifies the list itself)
+ *
+ * @see org.eclipse.core.databinding.observable.IChangeListener#handleChange(org.eclipse.core.databinding.observable.ChangeEvent)
+ *
+ * @param event
+ */
+ @Override
+ public void handleChange(ChangeEvent event) {
+ if (!isDisposed()) {
+ treeViewer.refresh();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (modelProperty != null) {
+ modelProperty.removeChangeListener(this);
+ }
+ super.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ updateControls();
+ // tree.setEnabled(!readOnly);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isReadOnly() {
+ return !tree.isEnabled();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLabel(String label) {
+ if (this.label == null) {
+ setLayout(new GridLayout(2, false));
+ }
+ super.setLabel(label);
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ tree.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void setModelObservable(IObservableList modelProperty) {
+ super.setModelObservable(modelProperty);
+ updateControls();
+ }
+
+ @Override
+ public void refreshValue() {
+ treeViewer.refresh();
+ }
+
+ /**
+ * Sets the direct creation mode.
+ * If direct creation is set to true, the {@link ReferenceValueFactory#createObject(org.eclipse.swt.widgets.Control)} method will be called when
+ * to add button is pressed.
+ * Otherwise, the dialog will be used.
+ *
+ * @param directCreation
+ */
+ public void setDirectCreation(boolean directCreation) {
+ this.directCreation = directCreation;
+ updateControls();
+ }
+
+ /**
+ * Adds a ISelectionChangedListener to this widget
+ *
+ * @param listener
+ */
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ treeViewer.addSelectionChangedListener(listener);
+ }
+
+ /**
+ * Removes a ISelectionChangedListener from this widget
+ *
+ * @param listener
+ */
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ treeViewer.removeSelectionChangedListener(listener);
+ }
+
+ /**
+ * Set the maximum number of values selected.
+ *
+ * @param upperBound
+ */
+ public void setUpperBound(int upperBound) {
+ this.upperBound = upperBound;
+ }
+
+ public void updateBoutons() {
+ /* Disable the button 'add' if the upperBound is reached */
+ if (this.upperBound != MANY) {
+ if (modelProperty.size() >= this.upperBound) {
+ add.setEnabled(false);
+ } else {
+ add.setEnabled(true);
+ }
+ }
+ }
+
+ @Override
+ public void changeColorField() {
+ // nothing to do here
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionDialog.java
new file mode 100644
index 00000000000..acab12ca40b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionDialog.java
@@ -0,0 +1,315 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Adapted code from MultipleValueSelectorDialog
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.util.ValueUtils;
+import org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * Object Chooser. Defines a standard popup for selecting
+ * multiple values. If this dialog is used to select or create model
+ * elements to be added to or removed from some element that is being
+ * edited, then it is important to {@linkplain #setContextElement(Object) set that contextual element} in this dialog.
+ *
+ * @author Vincent Lorenzo
+ *
+ * @see #setContextElement(Object)
+ *
+ */
+public class MultipleValueSelectionDialog extends SelectionDialog {
+
+ /**
+ * the widget providing the contents of the dialog
+ */
+ protected MultipleValueSelectionWidget widget;
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ */
+ public MultipleValueSelectionDialog(Shell parentShell, IElementSelector selector) {
+ this(parentShell, selector, null, false, false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ */
+ public MultipleValueSelectionDialog(Shell parentShell, IElementSelector selector, String title) {
+ this(parentShell, selector, title, false, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectionDialog(Shell parentShell, IElementSelector selector, boolean unique) {
+ this(parentShell, selector, null, unique, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectionDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered) {
+ this(parentShell, selector, title, unique, false, ValueUtils.MANY);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ * @param upperBound
+ * The maximum number of values selected.
+ */
+ public MultipleValueSelectionDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered, int upperBound) {
+ super(parentShell);
+ Assert.isNotNull(selector, "The element selector should be defined"); //$NON-NLS-1$
+ setHelpAvailable(false);
+ setTitle(title);
+ this.widget = createWidget(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ *
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ * @param ordered
+ * <code>true</code> if the edited feature is ordered
+ * @param upperBound
+ * The maximum number of values selected.
+ */
+ protected MultipleValueSelectionWidget createWidget(IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ return new MultipleValueSelectionWidget(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.dialogs.SelectionDialog#configureShell(org.eclipse.swt.widgets.Shell)
+ *
+ * @param shell
+ */
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setImage(org.eclipse.papyrus.infra.widgets.Activator.getDefault().getImage("/icons/papyrus.png")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.ui.dialogs.SelectionDialog#setInitialElementSelections(java.util.List)
+ *
+ * @param selectedElements
+ */
+ @Override
+ public void setInitialElementSelections(@SuppressWarnings("rawtypes") List selectedElements) {
+ super.setInitialElementSelections(selectedElements);
+ widget.setInitialSelections(getInitialElementSelections());
+ }
+
+
+ /**
+ * @see org.eclipse.ui.dialogs.SelectionDialog#setInitialSelections(java.lang.Object[])
+ *
+ * @param selectedElements
+ */
+ @Override
+ public void setInitialSelections(Object[] selectedElements) {
+ super.setInitialSelections(selectedElements);
+ widget.setInitialSelections(getInitialElementSelections());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void create() {
+ super.create();
+ createDialogContents();
+ getShell().pack();
+
+ this.widget.updateControls();
+
+ }
+
+ /**
+ * Create the contents of the dialog
+ */
+ protected void createDialogContents() {
+ Composite parent = getDialogArea();
+ this.widget.create(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Composite getDialogArea() {
+ return (Composite) super.getDialogArea();
+ }
+
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this editor. The {@link ReferenceValueFactory} is used to create
+ * new instances and edit existing ones.
+ *
+ * @param factory
+ * The {@link ReferenceValueFactory} to be used by this editor
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.widget.setFactory(factory);
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ *
+ */
+ @Override
+ protected void okPressed() {
+ setResult(this.widget.getSelection());
+ super.okPressed();
+ }
+
+ /**
+ * Indicates if the selected values should be unique (According to Object.equals())
+ *
+ * @param unique
+ */
+ public void setUnique(boolean unique) {
+ this.widget.setUnique(unique);
+ }
+
+ /**
+ * Indicates if the selected elements should be ordered
+ *
+ * @param ordered
+ */
+ public void setOrdered(boolean ordered) {
+ this.widget.setOrdered(ordered);
+ }
+
+ /**
+ * Set the selector to use
+ *
+ * @param selector
+ * the selector to use in the dialog
+ */
+ public void setSelector(IElementSelector selector) {
+ this.widget.setSelector(selector);
+ }
+
+ /**
+ * Set the maximum number of values selected.
+ *
+ * @param upperBound
+ */
+ public void setUpperBound(int upperBound) {
+ this.widget.setUpperBound(upperBound);
+ }
+
+ /**
+ * Sets the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @param contextElement
+ * the model element that is being edited
+ */
+ public void setContextElement(Object contextElement) {
+ this.widget.setContextElement(contextElement);
+ }
+
+ /**
+ * Queries the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @return the model element that is being edited
+ */
+ public Object getContextElement() {
+ return this.widget.getContextElement();
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#close()
+ *
+ * @return
+ */
+ @Override
+ public boolean close() {
+ if (this.widget != null) {
+ this.widget.dispose();
+ }
+ return super.close();
+ }
+
+ /**
+ * Sets the label provider used to display the selected elements
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.widget.setLabelProvider(labelProvider);
+ }
+
+ /**
+ *
+ * @return
+ * the widget
+ */
+ protected MultipleValueSelectionWidget getWidget() {
+ return this.widget;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionWithCheckBoxDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionWithCheckBoxDialog.java
new file mode 100644
index 00000000000..78b7823878f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectionWithCheckBoxDialog.java
@@ -0,0 +1,158 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget;
+import org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWithCheckboxWidget;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog adds a checkbox at the end of the {@link MultipleValueSelectorDialog}
+ *
+ * @author vl222926
+ *
+ */
+public class MultipleValueSelectionWithCheckBoxDialog extends MultipleValueSelectionDialog {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param unique
+ */
+ public MultipleValueSelectionWithCheckBoxDialog(Shell parentShell, IElementSelector selector, boolean unique) {
+ super(parentShell, selector, unique);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ * @param unique
+ * @param ordered
+ * @param upperBound
+ */
+ public MultipleValueSelectionWithCheckBoxDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered, int upperBound) {
+ super(parentShell, selector, title, unique, ordered, upperBound);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ * @param unique
+ * @param ordered
+ */
+ public MultipleValueSelectionWithCheckBoxDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered) {
+ super(parentShell, selector, title, unique, ordered);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ */
+ public MultipleValueSelectionWithCheckBoxDialog(Shell parentShell, IElementSelector selector, String title) {
+ super(parentShell, selector, title);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ */
+ public MultipleValueSelectionWithCheckBoxDialog(Shell parentShell, IElementSelector selector) {
+ super(parentShell, selector);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.MultipleValueSelectionDialog#createWidget(org.eclipse.papyrus.infra.widgets.editors.IElementSelector, boolean, boolean, int)
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ * @param upperbound
+ * @return
+ */
+ @Override
+ protected MultipleValueSelectionWidget createWidget(IElementSelector selector, boolean unique, boolean ordered, int upperbound) {
+ return new MultipleValueSelectionWithCheckboxWidget(selector, unique, ordered, upperbound);
+ }
+
+ /**
+ *
+ * @return
+ * the widget
+ */
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.MultipleValueSelectionDialog#getWidget()
+ *
+ * @return
+ */
+ @Override
+ protected MultipleValueSelectionWithCheckboxWidget getWidget() {
+ return (MultipleValueSelectionWithCheckboxWidget) super.getWidget();
+ }
+
+ /**
+ *
+ * @param text
+ * the text to display near the checkbox
+ * @param tooltip
+ * the tooltip to display for the checkbox
+ * @param isChecked
+ * the initial state of the checkbox
+ */
+ public void setCheckBoxValues(final String text, final String tooltip, final boolean isChecked) {
+ MultipleValueSelectionWithCheckboxWidget w = getWidget();
+ w.setCheckBoxValues(text, tooltip, isChecked);
+ }
+
+ /**
+ * this method allows to display or hide the checkbox
+ */
+ public void setDisplayCheckBox(boolean displayCheckBox) {
+ getWidget().setDisplayCheckBox(displayCheckBox);
+ }
+
+ /**
+ *
+ * @return
+ * the state of the checkbox button
+ */
+ public boolean isChecked() {
+ return getWidget().isChecked();
+ }
+
+ /**
+ *
+ * @return <code>true</code> if the checkbox must be displayed
+ */
+ public boolean isDisplayingCheckBox() {
+ return getWidget().isDisplayingCheckBox();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialog.java
new file mode 100644
index 00000000000..64256737146
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialog.java
@@ -0,0 +1,777 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+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.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * Object Chooser. Defines a standard popup for selecting
+ * multiple values. If this dialog is used to select or create model
+ * elements to be added to or removed from some element that is being
+ * edited, then it is important to {@linkplain #setContextElement(Object) set that contextual element} in this dialog.
+ *
+ * @author Camille Letavernier
+ *
+ * @see #setContextElement(Object)
+ *
+ * @deprecated use MultipleValueSelectionDialog instead
+ * @since Papyrus 1.1
+ */
+@Deprecated
+public class MultipleValueSelectorDialog extends SelectionDialog implements ISelectionChangedListener, IDoubleClickListener, IElementSelectionListener, SelectionListener {
+
+ public static final int MANY = -1;
+
+ /**
+ * The object selector
+ */
+ protected IElementSelector selector;
+
+ /**
+ * The SWT Composite in which the selector is drawn
+ */
+ protected Composite selectorSection;
+
+ /**
+ * The add/remove/addAll buttons section
+ */
+ protected Composite buttonsSection;
+
+ /**
+ * The up/down buttons section
+ */
+ protected Composite rightButtonsSection;
+
+ /**
+ * The listViewer for chosen elements
+ */
+ protected StructuredViewer selectedElementsViewer;
+
+ /**
+ * The list for chosen elements
+ */
+ protected Tree selectedElements;
+
+ /**
+ * The add action button
+ */
+ protected Button add;
+
+ /**
+ * The create action button
+ */
+ protected Button create;
+
+ /**
+ * The delete action button
+ */
+ protected Button delete;
+
+ /**
+ * The remove action button
+ */
+ protected Button remove;
+
+ /**
+ * The add all action button
+ */
+ protected Button addAll;
+
+ /**
+ * The remove all action button
+ */
+ protected Button removeAll;
+
+ /**
+ * the up action button
+ */
+ protected Button up;
+
+ /**
+ * the down action button
+ */
+ protected Button down;
+
+ /**
+ * The label provider for the listViewer of chosen elements
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The currently chosen elements
+ */
+ protected final Collection<Object> allElements;
+
+ /**
+ * Indicates if the values should be unique (according to Object.equals())
+ */
+ protected boolean unique;
+
+ /**
+ * Indicates if the list is ordered
+ */
+ protected boolean ordered;
+
+ /**
+ * The factory for creating new elements
+ */
+ protected ReferenceValueFactory factory;
+
+ /**
+ * The model element being edited (if any), to which elements are to be added or removed.
+ */
+ protected Object contextElement;
+
+ /**
+ * The list of newly created objects
+ */
+ protected Set<Object> newObjects = new HashSet<Object>();
+
+
+ /**
+ * The maximum number of values selected.
+ */
+ protected int upperBound;
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ */
+ public MultipleValueSelectorDialog(Shell parentShell, IElementSelector selector) {
+ this(parentShell, selector, null, false, false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ */
+ public MultipleValueSelectorDialog(Shell parentShell, IElementSelector selector, String title) {
+ this(parentShell, selector, title, false, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectorDialog(Shell parentShell, IElementSelector selector, boolean unique) {
+ this(parentShell, selector, null, unique, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectorDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered) {
+ this(parentShell, selector, title, unique, false, MANY);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The shell in which this dialog should be opened
+ * @param selector
+ * The element selector used by this dialog
+ * @param title
+ * The title of this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ * @param upperBound
+ * The maximum number of values selected.
+ */
+ public MultipleValueSelectorDialog(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered, int upperBound) {
+ super(parentShell);
+ Assert.isNotNull(selector, "The element selector should be defined"); //$NON-NLS-1$
+ this.selector = selector;
+ allElements = unique ? new LinkedHashSet<Object>() : new LinkedList<Object>();
+ setHelpAvailable(false);
+ setTitle(title);
+ this.unique = unique;
+ this.ordered = ordered;
+ this.upperBound = upperBound;
+ selector.addElementSelectionListener(this);
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setImage(Activator.getDefault().getImage("/icons/papyrus.png")); //$NON-NLS-1$
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void create() {
+ super.create();
+ createDialogContents();
+ getShell().pack();
+
+ updateControls();
+ }
+
+ /**
+ * Create the contents of the dialog
+ */
+ protected void createDialogContents() {
+ Composite parent = getDialogArea();
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns = 2;
+ layout.makeColumnsEqualWidth = true;
+
+ Composite selectorPane = new Composite(parent, SWT.NONE);
+ selectorPane.setLayout(new GridLayout(2, false));
+ selectorPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Composite selectedPane = new Composite(parent, SWT.NONE);
+ selectedPane.setLayout(new GridLayout(2, false));
+ selectedPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ createSelectorSection(selectorPane);
+ createControlsSection(selectorPane);
+ createListSection(selectedPane);
+ createRightButtonsSection(selectedPane);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Composite getDialogArea() {
+ return (Composite) super.getDialogArea();
+ }
+
+ /**
+ * Creates the selector section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createSelectorSection(Composite parent) {
+ selectorSection = new Composite(parent, SWT.NONE);
+ selectorSection.setLayout(new FillLayout());
+ selectorSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ selector.createControls(selectorSection);
+ }
+
+ /**
+ * Creates the main controls section (Add, remove, Add all, remove all)
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createControlsSection(Composite parent) {
+ buttonsSection = new Composite(parent, SWT.NONE);
+ buttonsSection.setLayout(new GridLayout(1, true));
+
+ add = new Button(buttonsSection, SWT.PUSH);
+ add.setImage(Activator.getDefault().getImage("/icons/arrow_right.gif")); //$NON-NLS-1$
+ add.addSelectionListener(this);
+ add.setToolTipText(Messages.MultipleValueSelectorDialog_AddSelectedElements);
+
+ remove = new Button(buttonsSection, SWT.PUSH);
+ remove.setImage(Activator.getDefault().getImage("/icons/arrow_left.gif")); //$NON-NLS-1$
+ remove.addSelectionListener(this);
+ remove.setToolTipText(Messages.MultipleValueEditor_RemoveSelectedElements);
+
+ addAll = new Button(buttonsSection, SWT.PUSH);
+ addAll.setImage(Activator.getDefault().getImage("/icons/arrow_double.gif")); //$NON-NLS-1$
+ addAll.addSelectionListener(this);
+ addAll.setToolTipText(Messages.MultipleValueSelectorDialog_AddAllElements);
+
+ /* Disable the bouton 'addAll' if currently chosen elements is greater than the maximum number of values selected */
+ if (this.upperBound != MANY && allElements.size() > this.upperBound) {
+ addAll.setEnabled(false);
+ }
+
+
+ removeAll = new Button(buttonsSection, SWT.PUSH);
+ removeAll.setImage(Activator.getDefault().getImage("/icons/arrow_left_double.gif")); //$NON-NLS-1$
+ removeAll.addSelectionListener(this);
+ removeAll.setToolTipText(Messages.MultipleValueSelectorDialog_RemoveAllElements);
+ }
+
+ /**
+ * Creates the list displaying the currently selected elements
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createListSection(Composite parent) {
+
+ selectedElements = new Tree(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ // selectedElements.addSelectionListener(this);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ selectedElements.setLayoutData(data);
+ selectedElementsViewer = new TreeViewer(selectedElements);
+
+ selectedElementsViewer.addSelectionChangedListener(this);
+ selectedElementsViewer.addDoubleClickListener(this);
+
+ selectedElementsViewer.setContentProvider(CollectionContentProvider.instance);
+
+ if (labelProvider != null) {
+ selectedElementsViewer.setLabelProvider(labelProvider);
+ }
+
+ selectedElementsViewer.setInput(allElements);
+ selector.setSelectedElements(allElements.toArray());
+ }
+
+ /**
+ * Creates the up/down controls section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createRightButtonsSection(Composite parent) {
+ rightButtonsSection = new Composite(parent, SWT.NONE);
+ rightButtonsSection.setLayout(new GridLayout(1, true));
+
+ up = new Button(rightButtonsSection, SWT.PUSH);
+ up.setImage(Activator.getDefault().getImage("/icons/Up_12x12.gif")); //$NON-NLS-1$
+ up.addSelectionListener(this);
+ up.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsUp);
+
+ down = new Button(rightButtonsSection, SWT.PUSH);
+ down.setImage(Activator.getDefault().getImage("/icons/Down_12x12.gif")); //$NON-NLS-1$
+ down.addSelectionListener(this);
+ down.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsDown);
+
+ create = new Button(rightButtonsSection, SWT.PUSH);
+ create.setImage(Activator.getDefault().getImage("/icons/Add_12x12.gif")); //$NON-NLS-1$
+ create.addSelectionListener(this);
+ create.setToolTipText(Messages.MultipleValueSelectorDialog_CreateNewElement);
+
+ delete = new Button(rightButtonsSection, SWT.PUSH);
+ delete.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ delete.addSelectionListener(this);
+ delete.setToolTipText(Messages.MultipleValueSelectorDialog_DeleteNewElement);
+ delete.setEnabled(false);
+ }
+
+ /**
+ * Sets the label provider used to display the selected elements
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ }
+
+ /**
+ * {@inheritDoc} Handles the events on one of the control buttons
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ * The event that occurred
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == add) {
+ addAction();
+ } else if (e.widget == remove) {
+ removeAction();
+ } else if (e.widget == addAll) {
+ addAllAction();
+ } else if (e.widget == removeAll) {
+ removeAllAction();
+ } else if (e.widget == up) {
+ upAction();
+ } else if (e.widget == down) {
+ downAction();
+ } else if (e.widget == create) {
+ createAction();
+ }
+
+ updateControls();
+ }
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this editor. The {@link ReferenceValueFactory} is used to create
+ * new instances and edit existing ones.
+ *
+ * @param factory
+ * The {@link ReferenceValueFactory} to be used by this editor
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.factory = factory;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public int open() {
+ allElements.clear();
+ allElements.addAll(getInitialElementSelections());
+ return super.open();
+ }
+
+ /**
+ * Handles the "Add" action
+ */
+ protected void addAction() {
+ Object[] elements = selector.getSelectedElements();
+ addElements(elements);
+ }
+
+ /**
+ * Handles the "Up" action
+ */
+ protected void upAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(allElements);
+ for (Object o : selection.toArray()) {
+ int oldIndex = list.indexOf(o);
+ if (oldIndex > 0) {
+ move(list, oldIndex, oldIndex - 1);
+ }
+ }
+
+ allElements.clear();
+ allElements.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Down" action
+ */
+ protected void downAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(allElements);
+
+ int maxIndex = list.size() - 1;
+
+ Object[] selectionArray = selection.toArray();
+ for (int i = selectionArray.length - 1; i >= 0; i--) {
+ Object o = selectionArray[i];
+ int oldIndex = list.indexOf(o);
+ if (oldIndex < maxIndex) {
+ move(list, oldIndex, oldIndex + 1);
+ }
+ }
+
+ allElements.clear();
+ allElements.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Create" action
+ */
+ protected void createAction() {
+ if (factory == null) {
+ return;
+ }
+
+ Object newObject;
+
+ try {
+ newObject = factory.createObject(this.create, contextElement);
+ } catch (OperationCanceledException e) {
+ // The user cancelled and we rolled back pending model changes
+ newObject = null;
+ }
+
+ if (newObject == null) {
+ return;
+ }
+
+ newObjects.add(newObject);
+ selector.newObjectCreated(newObject);
+
+ Object[] createdObjects = new Object[] { newObject };
+ addElements(createdObjects);
+
+ selector.setSelectedElements(allElements.toArray());
+ }
+
+ /**
+ * Moves an element from oldIndex to newIndex
+ *
+ * @param list
+ * The list in which to move the object
+ * @param oldIndex
+ * @param newIndex
+ */
+ private void move(java.util.List<Object> list, int oldIndex, int newIndex) {
+ int size = list.size();
+
+ if (oldIndex < 0 || oldIndex >= size) {
+ throw new IndexOutOfBoundsException("oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (newIndex < 0 || newIndex >= size) {
+ throw new IndexOutOfBoundsException("newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ Object element = list.remove(oldIndex);
+ list.add(newIndex, element);
+ }
+
+ /**
+ * Handles the "Remove" action
+ */
+ protected void removeAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+ if (selection.isEmpty()) {
+ return;
+ }
+
+ for (Object element : selection.toArray()) {
+ allElements.remove(element);
+ }
+
+ selector.setSelectedElements(allElements.toArray());
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Delete" action
+ */
+ protected void deleteAction() {
+ // nothing to do here
+ }
+
+ /**
+ * Handles the "Remove all" action
+ */
+ protected void removeAllAction() {
+ allElements.clear();
+ selector.setSelectedElements(new Object[0]);
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Add All" action
+ */
+ protected void addAllAction() {
+ Object[] elements = selector.getAllElements();
+ addElements(elements);
+ }
+
+ /**
+ * Adds the specified elements to the currently selected elements (For
+ * "Add" and "Add all" actions)
+ *
+ * @param elements
+ * The elements to be added
+ */
+ @Override
+ public void addElements(Object[] elements) {
+ if (elements != null) {
+ allElements.addAll(Arrays.asList(elements));
+ selectedElementsViewer.refresh();
+ }
+ }
+
+ @Override
+ protected void okPressed() {
+ if (factory != null) {
+ java.util.List<Object> objectsToValidate = new LinkedList<Object>();
+ for (Object object : newObjects) {
+ if (allElements.contains(object)) {
+ objectsToValidate.add(object);
+ }
+ }
+ factory.validateObjects(objectsToValidate);
+ selector.clearTemporaryElements();
+ }
+
+ setResult(new LinkedList<Object>(allElements));
+
+ super.okPressed();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing (see #doubleClick())
+ }
+
+ /**
+ * Indicates if the selected values should be unique (According to Object.equals())
+ *
+ * @param unique
+ */
+ public void setUnique(boolean unique) {
+ this.unique = unique;
+ updateControls();
+ }
+
+ /**
+ * Indicates if the selected elements should be ordered
+ *
+ * @param ordered
+ */
+ public void setOrdered(boolean ordered) {
+ this.ordered = ordered;
+ updateControls();
+ }
+
+ private void updateControls() {
+ updateControl(up, ordered);
+ updateControl(down, ordered);
+ updateControl(create, this.factory != null && this.factory.canCreateObject());
+
+ /* Disable the bouton 'add' if the upperBound is reached */
+ boolean canAdd = true;
+ if (this.upperBound != MANY) {
+ if (allElements.size() >= this.upperBound) {
+ canAdd = false;
+ }
+ }
+ updateControl(add, canAdd);
+ }
+
+ private void updateControl(Control control, boolean enabled) {
+ if (control != null) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ public void setSelector(IElementSelector selector) {
+ this.selector = selector;
+ }
+
+ /**
+ * Set the maximum number of values selected.
+ *
+ * @param upperBound
+ */
+ public void setUpperBound(int upperBound) {
+ this.upperBound = upperBound;
+ }
+
+ /**
+ * Sets the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @param contextElement
+ * the model element that is being edited
+ */
+ public void setContextElement(Object contextElement) {
+ this.contextElement = contextElement;
+ }
+
+ /**
+ * Queries the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @return the model element that is being edited
+ */
+ public Object getContextElement() {
+ return contextElement;
+ }
+
+ @Override
+ public boolean close() {
+ selector.removeElementSelectionListener(this);
+ return super.close();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Handles double click event on the right-panel tree viewer {@link #selectedElementsViewer}
+ *
+ */
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ removeAction();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Handles selection change event on the right-panel tree viewer {@link #selectedElementsViewer}
+ */
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateControls();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialogWithCheckBox.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialogWithCheckBox.java
new file mode 100644
index 00000000000..7d52b37c49b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueSelectorDialogWithCheckBox.java
@@ -0,0 +1,180 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog adds a checkbox at the end of the {@link MultipleValueSelectorDialog}
+ *
+ * @author vl222926
+ *
+ * @deprecated use {@link MultipleValueSelectionWithCheckBoxDialog} instead
+ * @since Papyrus 1.1.0
+ */
+@Deprecated
+public class MultipleValueSelectorDialogWithCheckBox extends MultipleValueSelectorDialog {
+
+ /** boolean indicating if the checkbox is checked */
+ protected boolean isChecked;
+
+ /** The text to display for the checkbox */
+ protected String text;
+
+ /** the tooltip to display for the checkbox */
+ protected String tooltip;
+
+ /** indicates if the checkbox must be displayed or not */
+ protected boolean displayCheckBox = true;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param unique
+ */
+ public MultipleValueSelectorDialogWithCheckBox(Shell parentShell, IElementSelector selector, boolean unique) {
+ super(parentShell, selector, unique);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ * @param unique
+ * @param ordered
+ * @param upperBound
+ */
+ public MultipleValueSelectorDialogWithCheckBox(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered, int upperBound) {
+ super(parentShell, selector, title, unique, ordered, upperBound);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ * @param unique
+ * @param ordered
+ */
+ public MultipleValueSelectorDialogWithCheckBox(Shell parentShell, IElementSelector selector, String title, boolean unique, boolean ordered) {
+ super(parentShell, selector, title, unique, ordered);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ * @param title
+ */
+ public MultipleValueSelectorDialogWithCheckBox(Shell parentShell, IElementSelector selector, String title) {
+ super(parentShell, selector, title);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * @param selector
+ */
+ public MultipleValueSelectorDialogWithCheckBox(Shell parentShell, IElementSelector selector) {
+ super(parentShell, selector);
+ }
+
+ /**
+ *
+ * @param text
+ * the text to display near the checkbox
+ * @param tooltip
+ * the tooltip to display for the checkbox
+ * @param isChecked
+ * the initial state of the checkbox
+ */
+ public void setCheckBoxValues(final String text, final String tooltip, final boolean isChecked) {
+ this.text = text;
+ this.tooltip = tooltip;
+ this.isChecked = isChecked;
+ }
+
+ /**
+ * this method allows to display or hide the checkbox
+ */
+ public void setDisplayCheckBox(boolean displayCheckBox) {
+ this.displayCheckBox = displayCheckBox;
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the disalog is displaying the checkbox
+ */
+ public boolean isDisplayingCheckBox() {
+ return this.displayCheckBox;
+ }
+
+ /**
+ * We Add a checkbox at the end of the dialog
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.MultipleValueSelectorDialog#createDialogContents()
+ *
+ */
+ @Override
+ protected void createDialogContents() {
+ super.createDialogContents();
+ if (this.displayCheckBox) {
+ final Composite parent = getDialogArea();
+ final Button button = new Button(parent, SWT.CHECK);
+ button.setText(this.text);
+ button.setToolTipText(this.tooltip);
+ button.setSelection(this.isChecked);
+ final SelectionListener listener = new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ isChecked = button.getSelection();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ };
+ button.addSelectionListener(listener);
+ }
+ }
+
+
+ /**
+ *
+ * @return
+ * the state of the checkbox button
+ */
+ public boolean isChecked() {
+ return this.isChecked;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultiplicityDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultiplicityDialog.java
new file mode 100644
index 00000000000..d110af0edff
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultiplicityDialog.java
@@ -0,0 +1,626 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.util.MultiplicityConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * The multiplicity dialog which allow to define 2 'modes' : The simple mode with a string combo editor and the advanced with 2 editors of ValueSpecification.
+ */
+public class MultiplicityDialog extends AbstractValueEditor implements SelectionListener, IChangeListener {
+
+ /**
+ * The string combo index in the list of editors.
+ */
+ protected static final int MULTIPLICITY_STRING_COMBO_INDEX = 0;
+
+ /**
+ * The lower value editor index in the list of editors.
+ */
+ protected static final int MULTIPLICITY_LOWER_VALUE_INDEX = 1;
+
+ /**
+ * The upper value editor index in the list of editors.
+ */
+ protected static final int MULTIPLICITY_UPPER_VALUE_INDEX = 2;
+
+
+ /**
+ * The stack layout for the 'mode' of editor to display.
+ */
+ protected StackLayout stackLayout;
+
+ /**
+ * The string combo editor for the 'simple' mode.
+ */
+ protected StringCombo stringComboEditor;
+
+ /**
+ * The parent stack layout composite.
+ */
+ protected Composite stackLayoutComposite;
+
+ /**
+ * The composite which contains the 'advanced' mode editors.
+ */
+ protected Composite doubleEditorsComposite;
+
+ /**
+ * The lower value specification editor.
+ */
+ protected AbstractReferenceDialog lowerValueEditor;
+
+ /**
+ * The upper value specification editor.
+ */
+ protected AbstractReferenceDialog upperValueEditor;
+
+ /**
+ * The switch editors button.
+ */
+ protected Button switchEditorsButton;
+
+ /**
+ * Boolean to determinate if the editors are read-only.
+ */
+ protected boolean readOnly;
+
+ /**
+ * The preference store.
+ */
+ protected IPreferenceStore preferenceStore;
+
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style.
+ */
+ public MultiplicityDialog(final Composite parent, final int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style.
+ * @param preferenceStore
+ * The preference store.
+ */
+ public MultiplicityDialog(final Composite parent, final int style, final IPreferenceStore preferenceStore) {
+ super(parent, style);
+
+ // Create the stack layout composite
+ stackLayout = new StackLayout();
+ stackLayoutComposite = new Composite(this, style);
+ stackLayoutComposite.setLayout(stackLayout);
+ stackLayoutComposite.setLayoutData(getDefaultLayoutData());
+
+ // Create the string combo editor
+ stringComboEditor = new StringCombo(stackLayoutComposite, style) {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#doBinding()
+ */
+ @Override
+ protected void doBinding() {
+ setWidgetObservable(getObservableValue());
+ super.doBinding();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#setModelObservable(org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ @Override
+ public void setModelObservable(IObservableValue modelProperty) {
+ this.modelProperty = modelProperty;
+ setWidgetObservable(getObservableValue());
+ super.setModelObservable(modelProperty);
+ updateControls();
+ }
+ };
+ stringComboEditor.setLayoutData(getDefaultLayoutData());
+
+ // Create the composite which contains the lower and the upper value specification editors
+ doubleEditorsComposite = new Composite(stackLayoutComposite, style);
+ final GridLayout layout = new GridLayout(2, true);
+ // Manage the height and the width (for a better visualization)
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ doubleEditorsComposite.setLayout(layout);
+ doubleEditorsComposite.setLayoutData(getDefaultLayoutData());
+
+ // Create the lower ValueSpecification editor
+ lowerValueEditor = createLowerValueSpecificationEditor(doubleEditorsComposite, style);
+ lowerValueEditor.setLayoutData(getDefaultLayoutData());
+
+ // Create the upper ValueSpecification editor
+ upperValueEditor = createUpperValueSpecificationEditor(doubleEditorsComposite, style);
+ upperValueEditor.setLayoutData(getDefaultLayoutData());
+
+ // Add a property change listener on the preference
+ this.preferenceStore = preferenceStore;
+ if (null != preferenceStore) {
+ this.preferenceStore.addPropertyChangeListener(new IPropertyChangeListener() {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent event) {
+ displayTopControl();
+ }
+ });
+ }
+
+ displayTopControl();
+
+ createButtons();
+ updateControls();
+ }
+
+ /**
+ * This allow to create the lower ValueSpecification editor.
+ *
+ * @param parent
+ * The parent composite
+ * @param style
+ * The style.
+ * @return The create lower ValueSpecification editor.
+ */
+ protected AbstractReferenceDialog createLowerValueSpecificationEditor(final Composite parent, final int style) {
+ return createValueSpecificationEditor(parent, style);
+ }
+
+ /**
+ * This allow to create the upper ValueSpecification editor.
+ *
+ * @param parent
+ * The parent composite
+ * @param style
+ * The style.
+ * @return The create upper ValueSpecification editor.
+ */
+ protected AbstractReferenceDialog createUpperValueSpecificationEditor(final Composite parent, final int style) {
+ return createValueSpecificationEditor(parent, style);
+ }
+
+ /**
+ * This allow to create the ValueSpecification editor.
+ *
+ * @param parent
+ * The parent composite
+ * @param style
+ * The style.
+ * @return The create ValueSpecification editor.
+ */
+ protected AbstractReferenceDialog createValueSpecificationEditor(final Composite parent, final int style) {
+ return new ReferenceDialog(parent, style);
+ }
+
+ /**
+ * This allow to create the buttons.
+ */
+ protected void createButtons() {
+ ((GridLayout) getLayout()).numColumns++;
+
+ switchEditorsButton = factory.createButton(this, null, SWT.PUSH);
+ switchEditorsButton.setImage(Activator.getDefault().getImage("/icons/Switch_12x12.gif")); //$NON-NLS-1$
+ switchEditorsButton.setToolTipText(Messages.MultiplicityReferenceDialog_SwitchEditors);
+ switchEditorsButton.addSelectionListener(this);
+ }
+
+ /**
+ * This allow to manage the stack layout top control displayed.
+ */
+ protected void displayTopControl() {
+ final String multiplicityEditorMode = preferenceStore.getString(MultiplicityConstants.MULTIPLICITY_EDITOR_MODE);
+ if (null != preferenceStore && null != multiplicityEditorMode) {
+ // If the advanced mode is used, display the double editors composite, else use the simple mode with the string combo
+ stackLayout.topControl = multiplicityEditorMode.equals(MultiplicityConstants.ADVANCED_MODE) ? doubleEditorsComposite : stringComboEditor;
+ } else {
+ if (null == stackLayout.topControl) {
+ stackLayout.topControl = stringComboEditor;
+ }
+ }
+
+ if (!stackLayoutComposite.isDisposed()) {
+ stackLayoutComposite.layout();
+ }
+ setReadOnly(readOnly);
+ }
+
+ /**
+ * This allow to define the switch action for the switch buttons.
+ */
+ protected void switchAction() {
+ if (null != preferenceStore) {
+ if (stackLayout.topControl.equals(stringComboEditor)) {
+ preferenceStore.setValue(MultiplicityConstants.MULTIPLICITY_EDITOR_MODE, MultiplicityConstants.ADVANCED_MODE);
+ } else {
+ preferenceStore.setValue(MultiplicityConstants.MULTIPLICITY_EDITOR_MODE, MultiplicityConstants.SIMPLE_MODE);
+ }
+ } else {
+ stackLayout.topControl = stackLayout.topControl.equals(stringComboEditor) ? doubleEditorsComposite : stringComboEditor;
+ }
+ // Refresh the read only value (because the lower and upper values must be different and multiplicity may not be update by simple editor)
+ displayTopControl();
+ }
+
+ /**
+ * Updates the displayed label for the current value
+ */
+ protected void updateLabels() {
+ lowerValueEditor.updateLabel();
+ upperValueEditor.updateLabel();
+ }
+
+ /**
+ * This allow to update the controls.
+ */
+ protected void updateControls() {
+ if (stackLayout.topControl.equals(stringComboEditor)) {
+ if (!stringComboEditor.isDisposed()) {
+ stringComboEditor.updateControls();
+ }
+ } else {
+ if (!lowerValueEditor.isDisposed()) {
+ lowerValueEditor.updateControls();
+ }
+
+ if (!upperValueEditor.isDisposed()) {
+ upperValueEditor.updateControls();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#update()
+ */
+ @Override
+ public void update() {
+ super.update();
+ if (stackLayout.topControl.equals(stringComboEditor)) {
+ if (!stringComboEditor.isDisposed()) {
+ stringComboEditor.update();
+ }
+ } else {
+ if (!lowerValueEditor.isDisposed()) {
+ lowerValueEditor.update();
+ }
+
+ if (!upperValueEditor.isDisposed()) {
+ upperValueEditor.update();
+ }
+ }
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractListEditor#doBinding()
+ */
+ @Override
+ protected void doBinding() {
+ super.doBinding();
+ if (null != stringComboEditor) {
+ stringComboEditor.doBinding();
+ }
+ if (null != lowerValueEditor) {
+ lowerValueEditor.doBinding();
+ }
+ if (null != upperValueEditor) {
+ upperValueEditor.doBinding();
+ }
+ modelProperty.addChangeListener(this);
+ }
+
+ /**
+ * Sets the content providers.
+ *
+ * @param providers
+ * The content providers for each editor.
+ */
+ public void setContentProviders(final List<IStaticContentProvider> providers) {
+ stringComboEditor.setContentProvider(getObjectFromList(providers, MULTIPLICITY_STRING_COMBO_INDEX));
+ lowerValueEditor.setContentProvider(getObjectFromList(providers, MULTIPLICITY_LOWER_VALUE_INDEX));
+ upperValueEditor.setContentProvider(getObjectFromList(providers, MULTIPLICITY_UPPER_VALUE_INDEX));
+ }
+
+ /**
+ * Sets the label providers.
+ *
+ * @param providers
+ * The label providers for each editor.
+ */
+ public void setLabelProviders(final List<ILabelProvider> providers) {
+ stringComboEditor.setLabelProvider(getObjectFromList(providers, MULTIPLICITY_STRING_COMBO_INDEX));
+ lowerValueEditor.setLabelProvider(getObjectFromList(providers, MULTIPLICITY_LOWER_VALUE_INDEX));
+ upperValueEditor.setLabelProvider(getObjectFromList(providers, MULTIPLICITY_UPPER_VALUE_INDEX));
+
+ updateControls();
+ updateLabels();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#getEditableType()
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * This allow to define if the string combo can be edited.
+ *
+ * @return <code>true</code> if the string combo can be edited, <code>false</code> otherwise.
+ */
+ protected boolean canEditStringCombo() {
+ return true;
+ }
+
+ /**
+ * This allow to define if the lower value can be edited.
+ *
+ * @return <code>true</code> if the lower value can be edited, <code>false</code> otherwise.
+ */
+ protected boolean canEditLowerValue() {
+ return true;
+ }
+
+ /**
+ * This allow to define if the upper value can be edited.
+ *
+ * @return <code>true</code> if the upper value can be edited, <code>false</code> otherwise.
+ */
+ protected boolean canEditUpperValue() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractListEditor#setModelObservable(org.eclipse.core.databinding.observable.list.IObservableList)
+ */
+ @Override
+ public void setModelObservable(final IObservableValue modelProperty) {
+ setWidgetObservable(modelProperty);
+ setEditorsModelObservable(modelProperty);
+ super.setModelObservable(modelProperty);
+
+ updateControls();
+ updateLabels();
+ }
+
+ /**
+ * Sets the model properties for the editors.
+ *
+ * @param modelProperty
+ * The observable value.
+ */
+ protected void setEditorsModelObservable(final IObservableValue modelProperty) {
+ if (null != modelProperty && modelProperty.getValue() instanceof List<?>) {
+ final Object stringComboObservableValue = getObjectFromList((List<?>) modelProperty.getValue(), MULTIPLICITY_STRING_COMBO_INDEX);
+ if (stringComboObservableValue instanceof IObservableValue) {
+ stringComboEditor.setModelObservable((IObservableValue) stringComboObservableValue);
+ }
+ final Object lowerValueObservableValue = getObjectFromList((List<?>) modelProperty.getValue(), MULTIPLICITY_LOWER_VALUE_INDEX);
+ if (lowerValueObservableValue instanceof IObservableValue) {
+ lowerValueEditor.setModelObservable((IObservableValue) lowerValueObservableValue);
+ }
+ final Object upperValueObservableValue = getObjectFromList((List<?>) modelProperty.getValue(), MULTIPLICITY_UPPER_VALUE_INDEX);
+ if (upperValueObservableValue instanceof IObservableValue) {
+ upperValueEditor.setModelObservable((IObservableValue) upperValueObservableValue);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)
+ */
+ @Override
+ public void setToolTipText(String text) {
+ stringComboEditor.setToolTipText(text);
+ lowerValueEditor.setToolTipText(Messages.MultiplicityReferenceDialog_LowerValueToolTip);
+ upperValueEditor.setToolTipText(Messages.MultiplicityReferenceDialog_UpperValueToolTip);
+ }
+
+ /**
+ * Sets the value factories.
+ *
+ * @param factories
+ * The Reference Value factories.
+ */
+ public void setValueFactories(final List<ReferenceValueFactory> factories) {
+ lowerValueEditor.setValueFactory(getObjectFromList(factories, MULTIPLICITY_LOWER_VALUE_INDEX));
+ upperValueEditor.setValueFactory(getObjectFromList(factories, MULTIPLICITY_UPPER_VALUE_INDEX));
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#setReadOnly(boolean)
+ */
+ @Override
+ public void setReadOnly(final boolean readOnly) {
+ this.readOnly = readOnly;
+ if (stackLayout.topControl.equals(stringComboEditor)) {
+ if (!stringComboEditor.isDisposed()) {
+ stringComboEditor.setReadOnly(readOnly || !canEditStringCombo());
+ }
+ } else {
+ if (!lowerValueEditor.isDisposed()) {
+ lowerValueEditor.setReadOnly(readOnly || !canEditLowerValue());
+ }
+ if (!upperValueEditor.isDisposed()) {
+ upperValueEditor.setReadOnly(readOnly || !canEditUpperValue());
+ }
+ }
+ updateControls();
+ }
+
+ /**
+ * This allow to set the direct creation of the lower and the upper value editors.
+ *
+ * @param directCreation
+ * The direct creation value.
+ */
+ public void setDirectCreation(final boolean directCreation) {
+ lowerValueEditor.setDirectCreation(directCreation);
+ upperValueEditor.setDirectCreation(directCreation);
+ updateControls();
+ }
+
+ /**
+ * This allow to set the mandatory of the lower and the upper value editors.
+ *
+ * @param mandatory
+ * The mandatory value.
+ */
+ public void setMandatory(final boolean mandatory) {
+ lowerValueEditor.setMandatory(mandatory);
+ upperValueEditor.setMandatory(mandatory);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ Widget widget = e.widget;
+ if (widget == switchEditorsButton) {
+ switchAction();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetDefaultSelected(final SelectionEvent e) {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (null != stringComboEditor) {
+ stringComboEditor.dispose();
+ }
+ if (null != lowerValueEditor) {
+ lowerValueEditor.dispose();
+ }
+ if (null != upperValueEditor) {
+ upperValueEditor.dispose();
+ }
+ super.dispose();
+ }
+
+ /**
+ * Get the object index from the list of objects.
+ *
+ * @param listObjects
+ * The list of objects.
+ * @param index
+ * The index object to get.
+ * @return The object at the index position or <code>null</code>.
+ */
+ protected <T> T getObjectFromList(final List<T> listObjects, final int index) {
+ T object = null;
+ if (null != listObjects && !listObjects.isEmpty()) {
+ if (listObjects.size() > index) {
+ object = listObjects.get(index);
+ }
+ }
+ return object;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#getValue()
+ */
+ @Override
+ public Object getValue() {
+ return modelProperty.getValue();
+ }
+
+ /**
+ * Redefine this method to re-affect the correct observable value to each editors.
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.databinding.observable.IChangeListener#handleChange(org.eclipse.core.databinding.observable.ChangeEvent)
+ */
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ // Only refresh the model observables and the read only value
+ setEditorsModelObservable(modelProperty);
+ setReadOnly(readOnly);
+ // The others variables (labelProviders, contentProviders, mandatory and directCreation) don't need to change
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceCombo.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceCombo.java
new file mode 100644
index 00000000000..10cfb693326
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceCombo.java
@@ -0,0 +1,330 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 435420
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.databinding.ComboObservableValue;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.papyrus.infra.widgets.providers.UnsetObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * An editor representing a single reference as a Combo Box
+ * This Editor needs a ContentProvider and a LabelProvider,
+ * describing the objects that can be referred by this property
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ReferenceCombo extends AbstractValueEditor { // implements SelectionListener {
+
+ /**
+ * The viewer displaying the available values from the model
+ */
+ protected ComboViewer viewer;
+
+ /**
+ * The combo used to select the reference
+ */
+ protected CCombo combo;
+
+ protected boolean unsettable;
+
+ // protected Button unset;
+
+ protected EncapsulatedContentProvider contentProvider;
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this editor is diplayed
+ * @param style
+ * The style for this editor's combo
+ */
+ public ReferenceCombo(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which this editor is diplayed
+ * @param style
+ * The style for this editor's combo
+ * @param label
+ * The label for this editor
+ */
+ public ReferenceCombo(Composite parent, int style, String label) {
+ super(parent, label);
+
+ combo = factory.createCCombo(this, style | SWT.BORDER);
+ combo.setBackground(new Color(combo.getDisplay(), 255, 255, 255));
+ combo.setLayoutData(getDefaultLayoutData());
+ combo.setEditable(false);
+
+ viewer = new ComboViewer(combo);
+
+ // unset = new Button(this, SWT.PUSH);
+ // unset.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ // unset.setToolTipText("Unset the current value");
+ // unset.addSelectionListener(this);
+
+ ((GridLayout) getLayout()).numColumns++;
+
+ setCommitOnFocusLost(combo);
+ controlDecoration = new ControlDecoration(combo, SWT.TOP | SWT.LEFT);
+ GridData gridData = getDefaultLayoutData();
+ combo.setLayoutData(gridData);
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+
+ combo.addFocusListener(new FocusAdapter() {
+
+ @Override
+ public void focusGained(FocusEvent paramFocusEvent) {
+ acceptingFocus();
+ }
+ });
+ }
+
+ /**
+ * Sets the Content and Label providers for this editor
+ *
+ * @param contentProvider
+ *
+ * @param labelProvider
+ */
+ public void setProviders(IStaticContentProvider contentProvider, ILabelProvider labelProvider) {
+ Assert.isNotNull(contentProvider, "The content provider should not be null"); //$NON-NLS-1$
+ setContentProvider(contentProvider);
+
+ if (labelProvider != null) {
+ setLabelProvider(labelProvider);
+ }
+ }
+
+ /**
+ * Sets the content provider for this combo. The Content provider should
+ * specify the objects that can be referred by this property
+ *
+ * @param provider
+ */
+ public void setContentProvider(IStaticContentProvider provider) {
+ this.contentProvider = new EncapsulatedContentProvider(provider);
+ viewer.setContentProvider(contentProvider);
+ viewer.setInput(""); //$NON-NLS-1$
+ updateControls();
+ doBinding();
+ }
+
+ @Override
+ protected void doBinding() {
+ if (contentProvider == null || modelProperty == null) {
+ return;
+ }
+
+ if (widgetObservable == null) {
+ setWidgetObservable(getObservableValue(), true);
+ }
+
+ if (modelProperty instanceof AggregatedObservable) {
+ if (((AggregatedObservable) modelProperty).hasDifferentValues()) {
+ contentProvider.addTemporaryElement(UnchangedObject.instance);
+ viewer.refresh();
+ }
+ }
+ super.doBinding();
+ }
+
+ protected IObservableValue getObservableValue() {
+ return new ComboObservableValue(viewer, modelProperty);
+ }
+
+ /**
+ * The Label provider associated to the available objects that
+ * can be referred by this property
+ *
+ * @param provider
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ viewer.setLabelProvider(provider);
+ }
+
+ /**
+ * Retrieves the ComboViewer associated to this Editor
+ *
+ * @return
+ * The ComboViewer associated to this editor
+ */
+ public ComboViewer getViewer() {
+ return viewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ if (selection.isEmpty()) {
+ return null;
+ }
+ return selection.getFirstElement();
+ }
+
+ /**
+ * Sets the value for this widget
+ *
+ * @param value
+ */
+ public void setValue(Object value) {
+ if (value == null) {
+ viewer.setSelection(new StructuredSelection());
+ } else {
+ viewer.setSelection(new StructuredSelection(value), true);
+ }
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ combo.setEnabled(!readOnly);
+ updateControls();
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !combo.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ combo.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ public void setUnsettable(boolean unsettable) {
+ this.unsettable = unsettable;
+ updateControls();
+ }
+
+ /**
+ * Updates the controls display
+ */
+ protected void updateControls() {
+ // setExclusion(unset, !unsettable);
+
+ // if(isReadOnly() && unsettable) {
+ // unset.setEnabled(false);
+ // }
+
+ if (contentProvider != null) {
+ if (unsettable) {
+ contentProvider.addTemporaryElement(UnsetObject.instance);
+ } else {
+ contentProvider.removeTemporaryElement(UnsetObject.instance);
+ }
+ viewer.refresh();
+ }
+ }
+
+ /**
+ * Changes the viewer for this editor.
+ * The viewer should use a CCombo
+ *
+ * @param comboViewer
+ */
+ public void setViewer(ComboViewer comboViewer) {
+ this.viewer = comboViewer;
+ this.combo = viewer.getCCombo();
+ }
+
+ // FIXME error avec multiplicit� nulllpointerexception l285
+ @Override
+ public void updateStatus(IStatus status) {
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+
+
+ }
+
+ // protected void unsetAction() {
+ // viewer.setSelection(StructuredSelection.EMPTY);
+ // if(modelProperty != null) {
+ // modelProperty.setValue(null);
+ // }
+ // }
+
+ // public void widgetSelected(SelectionEvent e) {
+ // if(e.widget == unset) {
+ // unsetAction();
+ // }
+ // }
+
+ // public void widgetDefaultSelected(SelectionEvent e) {
+ // //Nothing
+ // }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceDialog.java
new file mode 100644
index 00000000000..95775b4483d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ReferenceDialog.java
@@ -0,0 +1,616 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 402525
+ * Christian W. Damus (CEA) - bug 443497
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.databinding.CLabelObservableValue;
+import org.eclipse.papyrus.infra.widgets.databinding.ReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.databinding.StyledTextReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+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.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * An editor representing a single reference as a Label A filtered selection
+ * dialog is used to edit the value. Also offers support for unsetting the
+ * value. This Editor needs a ContentProvider, and may use an optional
+ * LabelProvider, describing the objects that can be referred by this property
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ReferenceDialog extends AbstractReferenceDialog implements SelectionListener {
+
+ /**
+ * The CLabel displaying the current value
+ */
+ protected final CLabel currentValueLabel;
+
+ /**
+ * The Button used to browse the available values
+ */
+ protected Button browseValuesButton;
+
+ /**
+ * The Button used to create a new instance
+ */
+ protected Button createInstanceButton;
+
+ /**
+ * The Button used to edit the current object
+ */
+ protected Button editInstanceButton;
+
+ /**
+ * The Button used to unset the current value
+ */
+ protected Button unsetButton;
+
+ /**
+ * The label provider used to display the values in both the label and the
+ * selection dialog
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The content provider, providing the different possible values for the
+ * input object
+ */
+ protected IStaticContentProvider contentProvider;
+
+ /**
+ * The dialog used to select the value
+ */
+ protected final ITreeSelectorDialog dialog;
+
+ /**
+ * The current value for this editor
+ */
+ protected Object value;
+
+ /**
+ * The factory used to create or edit objects directly from this editor
+ */
+ protected ReferenceValueFactory valueFactory;
+
+ private boolean directCreation;
+
+ private ControlDecoration controlDecoration;
+
+ protected boolean error = false;
+
+ private Timer timer;
+
+ private TimerTask changeColorTask;
+
+ private boolean edit = false;
+
+ /**
+ *
+ * Constructs a new ReferenceDialog in the given parent Composite. The style
+ * will be applied to the CLabel displaying the current value.
+ *
+ * @param parent
+ * @param style
+ */
+ public ReferenceDialog(Composite parent, int style) {
+ super(parent, style);
+ GridData gridData = getDefaultLayoutData();
+
+ currentValueLabel = factory.createCLabel(this, null, factory.getBorderStyle() | style);
+ currentValueLabel.setLayoutData(gridData);
+ currentValueLabel.addMouseListener(new MouseListener() {
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ editAction(); // TODO : Try to determine whether the double
+ // click should call the edit, create or browse
+ // action
+ // e.g. if the value is null, try to browse. If we cannot
+ // browse, try to create an instance.
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ // Nothing
+ }
+
+ });
+
+ dialog = createDialog(parent.getShell());
+
+ createButtons();
+ updateControls();
+ controlDecoration = new ControlDecoration(currentValueLabel, SWT.TOP | SWT.LEFT);
+
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ }
+
+ protected ITreeSelectorDialog createDialog(Shell shell) {
+ return new TreeSelectorDialog(shell);
+ }
+
+ protected void createButtons() {
+ ((GridLayout) getLayout()).numColumns += 4;
+
+ browseValuesButton = factory.createButton(this, null, SWT.PUSH);
+ browseValuesButton.setImage(Activator.getDefault().getImage("/icons/browse_12x12.gif")); //$NON-NLS-1$
+ browseValuesButton.setToolTipText(Messages.ReferenceDialog_EditValue);
+ browseValuesButton.addSelectionListener(this);
+
+ createInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ createInstanceButton.setImage(Activator.getDefault().getImage("/icons/Add_12x12.gif")); //$NON-NLS-1$
+ createInstanceButton.setToolTipText(Messages.ReferenceDialog_CreateANewObject);
+ createInstanceButton.addSelectionListener(this);
+
+ editInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ editInstanceButton.setImage(Activator.getDefault().getImage("/icons/Edit_12x12.gif")); //$NON-NLS-1$
+ editInstanceButton.setToolTipText(Messages.ReferenceDialog_EditTheCurrentValue);
+ editInstanceButton.addSelectionListener(this);
+
+ unsetButton = factory.createButton(this, null, SWT.PUSH);
+ unsetButton.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ unsetButton.setToolTipText(Messages.ReferenceDialog_UnsetValue);
+ unsetButton.addSelectionListener(this);
+ }
+
+ /**
+ * The action executed when the "browse" button is selected Choose a value
+ * from a selection of already created objects
+ */
+ protected void browseAction() {
+ setInitialSelection(Collections.singletonList(getValue()));
+ int result = dialog.open();
+ if (result == Window.OK) {
+ Object[] newValue = dialog.getResult();
+ if (newValue == null) {
+ return;
+ }
+
+ if (newValue.length == 0) {
+ setValue(null);
+ } else {
+ Object value = newValue[0];
+ if (contentProvider instanceof IAdaptableContentProvider) {
+
+ value = ((IAdaptableContentProvider) contentProvider).getAdaptedValue(value);
+ }
+ setValue(value);
+ }
+ }
+ }
+
+ /**
+ * The action executed when the "create" button is selected Create a new
+ * instance and assign it to this reference
+ */
+ protected void createAction() {
+ if (valueFactory != null && valueFactory.canCreateObject()) {
+ final Object context = getContextElement();
+ getOperationExecutor(context).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object value = valueFactory.createObject(createInstanceButton, context);
+ if (value == null) {
+ // Cancel the operation
+ throw new OperationCanceledException();
+ }
+ Collection<Object> validatedObjects = valueFactory.validateObjects(Collections.singleton(value));
+ if (!validatedObjects.isEmpty()) {
+ setValue(validatedObjects.iterator().next());
+ }
+ }
+ }, NLS.bind(Messages.ReferenceDialog_setOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "edit" button is selected Edits the object
+ * that is currently selected
+ */
+ protected void editAction() {
+ currentValueLabel.setBackground(EDIT);
+ edit = true;
+ final Object currentValue = getValue();
+ if (currentValue != null && valueFactory != null && valueFactory.canEdit()) {
+ getOperationExecutor(currentValue).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object newValue = valueFactory.edit(editInstanceButton, currentValue);
+
+ // Per the contract of ReferenceValueFactory::edit(), a null return means the object was edited "in place."
+ // In that case, there is nothing further to do
+ if ((newValue != null) && (newValue != currentValue)) {
+ setValue(newValue);
+ }
+
+ updateLabel();
+ }
+ }, NLS.bind(Messages.ReferenceDialog_editOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "unset" button is selected Sets the current
+ * reference to null
+ */
+ protected void unsetAction() {
+ setValue(null);
+ }
+
+ /**
+ * Updates the displayed label for the current value
+ */
+ @Override
+ public void updateLabel() {
+ if (binding != null) {
+ binding.updateModelToTarget();
+
+ } else {
+ if (null != labelProvider) {
+ currentValueLabel.setImage(labelProvider.getImage(getValue()));
+ currentValueLabel.setText(labelProvider.getText(getValue()));
+ }
+ }
+ }
+
+ /**
+ * Sets the Content provider for this editor
+ *
+ * @param provider
+ * The content provider used to retrieve the possible values for
+ * this Reference
+ */
+ @Override
+ public void setContentProvider(IStaticContentProvider provider) {
+ dialog.setContentProvider(new EncapsulatedContentProvider(provider));
+ if (getValue() != null) {
+ setInitialSelection(Collections.singletonList(getValue()));
+ }
+
+ this.contentProvider = provider;
+ }
+
+ /**
+ * Sets the Label provider for this editor If the label provider is null, a
+ * default one will be used. The same label provider is used for both the
+ * editor's label and the selection dialog.
+ *
+ * @param provider
+ * The label provider
+ */
+ @Override
+ public void setLabelProvider(ILabelProvider provider) {
+ if (provider == null) {
+ setLabelProvider(new LabelProvider());
+ return;
+ }
+
+ dialog.setLabelProvider(provider);
+ this.labelProvider = provider;
+ if (widgetObservable != null) {
+ ((CLabelObservableValue) widgetObservable).setLabelProvider(labelProvider);
+ }
+ updateLabel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLabel(String label) {
+ super.setLabel(label);
+ dialog.setTitle(label);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ if (modelProperty != null) {
+ return modelProperty.getValue();
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isReadOnly() {
+ return !currentValueLabel.isEnabled();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doBinding() {
+ super.doBinding();
+ }
+
+ protected void setInitialSelection(List<?> initialValues) {
+ dialog.setInitialElementSelections(initialValues);
+ }
+
+ @Override
+ public void setModelObservable(IObservableValue modelProperty) {
+ setWidgetObservable(createWidgetObservable(modelProperty));
+ super.setModelObservable(modelProperty);
+ updateControls();
+ }
+
+ /**
+ * This allow to create the widget observable value.
+ *
+ * @param modelProperty
+ * The current observable value.
+ * @return The created {@link StyledTextReferenceDialogObservableValue}.
+ */
+ protected IObservableValue createWidgetObservable(final IObservableValue modelProperty) {
+ return new ReferenceDialogObservableValue(this, this.currentValueLabel, modelProperty, labelProvider);
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ super.setLabelToolTipText(text);
+ currentValueLabel.setToolTipText(text);
+ }
+
+ @Override
+ public void setValueFactory(ReferenceValueFactory factory) {
+ valueFactory = factory;
+ updateControls();
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Widget widget = e.widget;
+ if (widget == browseValuesButton) {
+ browseAction();
+ } else if (widget == createInstanceButton) {
+ createAction();
+ } else if (widget == editInstanceButton) {
+ editAction();
+ } else if (widget == unsetButton) {
+ unsetAction();
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ /**
+ * Updates the buttons' status
+ */
+ @Override
+ public void updateControls() {
+ // Check if the edit & create buttons should be displayed
+ boolean exclude = valueFactory == null || !valueFactory.canCreateObject();
+ setExclusion(editInstanceButton, exclude);
+ setExclusion(createInstanceButton, exclude);
+
+ setExclusion(browseValuesButton, directCreation);
+
+ browseValuesButton.setEnabled(!readOnly);
+
+ // If they are displayed, check if they should be enabled
+ if (!exclude) {
+ editInstanceButton.setEnabled(valueFactory != null && valueFactory.canEdit() && getValue() != null);
+ createInstanceButton.setEnabled(valueFactory != null && valueFactory.canCreateObject() && !readOnly);
+ }
+
+ // Do not display unset if the value is mandatory
+ setExclusion(unsetButton, mandatory);
+ if (!mandatory) {
+ boolean enabled = !readOnly;
+ enabled = enabled && getValue() != null;
+
+ unsetButton.setEnabled(enabled);
+ }
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ updateControls();
+ }
+
+ @Override
+ public void setDirectCreation(boolean directCreation) {
+ this.directCreation = directCreation;
+ updateControls();
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ try {
+ if (modelProperty != null) {
+ modelProperty.setValue(value);
+ error = false;
+ }
+ } catch (Exception e) {
+ error = true;
+
+ }
+
+ updateControls();
+ updateLabel();
+ commit();
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.StructuredViewer#setInput(Object)
+ * @param input
+ */
+ public void setInput(Object input) {
+ this.dialog.setInput(input);
+ }
+
+ @Override
+ public void setMandatory(boolean mandatory) {
+ this.mandatory = mandatory;
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+
+ if (error) {
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(Messages.ReferenceDialog_0);
+ controlDecoration.setDescriptionText(Messages.ReferenceDialog_1);
+ controlDecoration.show();
+ currentValueLabel.setBackground(ERROR);
+ currentValueLabel.update();
+
+
+ } else {
+ controlDecoration.hide();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ if (timer != null) {
+ timer.cancel();
+ }
+ super.dispose();
+ }
+
+ private void cancelCurrentTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ }
+
+ @Override
+ public void changeColorField() {
+ if (!error & !edit) {
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ if (ReferenceDialog.this.isDisposed()) {
+ return;
+ }
+ ReferenceDialog.this.getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (ReferenceDialog.this.isDisposed()) {// Bug 434787 : Shouldn't not execute the timer thread if the widget is disposed
+ return;
+ }
+ currentValueLabel.setBackground(DEFAULT);
+ currentValueLabel.update();
+ }
+
+
+ });
+ }
+ };
+
+ if (errorBinding) {
+ currentValueLabel.setBackground(ERROR);
+ currentValueLabel.update();
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ currentValueLabel.setBackground(VALID);
+ currentValueLabel.update();
+ break;
+ case IStatus.ERROR:
+ currentValueLabel.setBackground(ERROR);
+ currentValueLabel.update();
+ break;
+
+ }
+ }
+ } else {
+ currentValueLabel.setBackground(DEFAULT);
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionEditor.java
new file mode 100644
index 00000000000..e385f80a43d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionEditor.java
@@ -0,0 +1,543 @@
+/*****************************************************************************
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+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.Label;
+import org.eclipse.swt.widgets.List;
+
+/**
+ *
+ * This class provides an editor to select easily elements
+ * In the left side, we have the possible element to select and in the right side, we have the current selection
+ * Moreover, its possible to add a Button to provide some action. Often this button shall be used to create new element
+ *
+ */
+public class SelectionEditor extends Composite implements SelectionListener {
+
+ /** the initial selection */
+ protected final java.util.List<Object> initialSelection;
+
+ /** The object selector */
+ private IElementSelector selector;
+
+ /** The SWT Composite in which the selector is drawn */
+ protected Composite selectorSection;
+
+ /** The message section */
+ protected Composite messageSection;
+
+ /** The additional button section */
+ protected Composite createAdditionalButtonSection;
+
+ /** The up/down buttons section */
+ protected Composite rightButtonsSection;
+
+ /** The listViewer for chosen elements */
+ protected ListViewer selectedElementsViewer;
+
+ /** The list for chosen elements */
+ protected List selectedElements;
+
+ /** The add action button */
+ private Button add;
+
+ /** The remove action button */
+ private Button remove;
+
+ /** The add all action button */
+ private Button addAll;
+
+ /** The remove all action button */
+ private Button removeAll;
+
+ /** the up action button */
+ private Button up;
+
+ /** the down action button */
+ private Button down;
+
+ /** The label provider for the listViewer of chosen elements */
+ private ILabelProvider labelProvider;
+
+ /** The currently chosen elements */
+ protected final Collection<Object> currentSelection;
+
+ /** the listener for the additional button */
+ private SelectionListener additionalButtonSelectionListener;
+
+ /** the message for the editor */
+ private String message;
+
+
+ /*
+ * This dialog can provide a Button to do some optional action
+ */
+
+ /** Indicates if the dialog provides a button */
+ private boolean withAdditionalButton = false;
+
+ /** the label of the button */
+ private String additionalButtonLabel = null;
+
+ /** the button */
+ private Button additionalButton;
+
+ /** The add/remove/addAll buttons section */
+ protected Composite buttonSection;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * the parent of this composite
+ * @param selector
+ * the selector
+ * @param labelProvider
+ * the label provider
+ * @param initialSelection
+ * the initial selection
+ */
+ public SelectionEditor(Composite parent, IElementSelector selector, ILabelProvider labelProvider, java.util.List<Object> initialSelection) {
+ super(parent, SWT.NONE);
+ this.selector = selector;
+ this.labelProvider = labelProvider;
+ this.initialSelection = new ArrayList<Object>();
+ for (Object current : initialSelection) {
+ this.initialSelection.add(current);
+ }
+ currentSelection = initialSelection;
+ }
+
+ /**
+ * This methods create this editor
+ */
+ public void create() {
+ Composite parent = this;
+ GridLayout layout = new GridLayout(1, true);
+ GridData data = new GridData();
+ data.grabExcessHorizontalSpace = true;
+ data.grabExcessVerticalSpace = true;
+ parent.setLayout(layout);
+ createMessageSection(parent);
+ createBody(parent);
+ createCreateButtonSection(parent);
+ }
+
+ /**
+ * This method create the body of the editor :
+ * <ul>
+ * <li>the selector</li>
+ * <li>the list</li>
+ * <li>the buttons Add, AddAll, Remove, RemoveAll, Up, Down</li>
+ * </ul>
+ *
+ * @param parent
+ * the parent composite
+ */
+ protected void createBody(Composite parent) {
+
+ Composite par = new Composite(parent, SWT.NONE);
+ createSelectorSection(par);
+ createControlsSection(par);
+ createListSection(par);
+ createRightButtonsSection(par);
+ GridLayout layout = new GridLayout();
+ layout.makeColumnsEqualWidth = false;
+ layout.numColumns = 4;
+ par.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ par.setLayoutData(data);
+
+ }
+
+ /**
+ * Creates the Message section
+ *
+ * @param parent
+ * the parent of the {@link Composite}
+ */
+ protected void createMessageSection(Composite parent) {
+ messageSection = new Composite(parent, SWT.NONE);
+ Label label = new Label(messageSection, SWT.NONE);
+ label.setText(message);
+ messageSection.setLayout(new FillLayout(SWT.HORIZONTAL));
+ }
+
+ /**
+ * Creates the button section
+ *
+ * @param parent
+ * the parent of the {@link Composite}
+ */
+ protected void createCreateButtonSection(Composite parent) {
+ if (this.withAdditionalButton) {
+ buttonSection = new Composite(parent, SWT.NONE);
+ additionalButton = new Button(buttonSection, SWT.PUSH);
+ if (additionalButtonLabel != null) {
+ additionalButton.setText(additionalButtonLabel);
+ }
+ buttonSection.setLayout(new FillLayout());
+ this.additionalButton.addSelectionListener(additionalButtonSelectionListener);
+ }
+ }
+
+ /**
+ * Creates the selector section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ protected void createSelectorSection(Composite parent) {
+ selectorSection = new Composite(parent, SWT.NONE);
+ selectorSection.setLayout(new FillLayout());
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.widthHint = 400;
+
+ // data.exclude = true;
+ selectorSection.setLayoutData(data);
+ selector.createControls(selectorSection);
+
+ }
+
+ /**
+ * Creates the main controls section (Add, remove, Add all, remove all)
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ protected void createControlsSection(Composite parent) {
+ buttonSection = new Composite(parent, SWT.NONE);
+ buttonSection.setLayout(new GridLayout(1, true));
+
+ add = new Button(buttonSection, SWT.PUSH);
+ add.setImage(Activator.getDefault().getImage("/icons/arrow_right.gif")); //$NON-NLS-1$
+ add.addSelectionListener(this);
+ add.setToolTipText(Messages.MultipleValueSelectorDialog_AddSelectedElements);
+
+ remove = new Button(buttonSection, SWT.PUSH);
+ remove.setImage(Activator.getDefault().getImage("/icons/arrow_left.gif")); //$NON-NLS-1$
+ remove.addSelectionListener(this);
+ remove.setToolTipText(Messages.MultipleValueEditor_RemoveSelectedElements);
+
+ addAll = new Button(buttonSection, SWT.PUSH);
+ addAll.setImage(Activator.getDefault().getImage("/icons/arrow_double.gif")); //$NON-NLS-1$
+ addAll.addSelectionListener(this);
+ addAll.setToolTipText(Messages.MultipleValueSelectorDialog_AddAllElements);
+
+ removeAll = new Button(buttonSection, SWT.PUSH);
+ removeAll.setImage(Activator.getDefault().getImage("/icons/arrow_left_double.gif")); //$NON-NLS-1$
+ removeAll.addSelectionListener(this);
+ removeAll.setToolTipText(Messages.MultipleValueSelectorDialog_RemoveAllElements);
+ }
+
+
+ /**
+ * Creates the list displaying the currently selected elements
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ protected void createListSection(Composite parent) {
+ Composite listSection = new Composite(parent, SWT.NONE);
+ selectedElements = new List(listSection, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.widthHint = 400;
+ listSection.setLayout(new FillLayout());
+ listSection.setLayoutData(data);
+
+ selectedElementsViewer = new ListViewer(selectedElements);
+
+ selectedElementsViewer.setContentProvider(CollectionContentProvider.instance);
+
+ if (labelProvider != null) {
+ selectedElementsViewer.setLabelProvider(labelProvider);
+ }
+
+ selectedElementsViewer.setInput(currentSelection);
+ selector.setSelectedElements(currentSelection.toArray());
+
+ }
+
+ /**
+ * Creates the up/down controls section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ protected void createRightButtonsSection(Composite parent) {
+ rightButtonsSection = new Composite(parent, SWT.NONE);
+ rightButtonsSection.setLayout(new GridLayout(1, true));
+
+ up = new Button(rightButtonsSection, SWT.PUSH);
+ up.setImage(Activator.getDefault().getImage("/icons/Up_12x12.gif")); //$NON-NLS-1$
+ up.addSelectionListener(this);
+ up.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsUp);
+
+ down = new Button(rightButtonsSection, SWT.PUSH);
+ down.setImage(Activator.getDefault().getImage("/icons/Down_12x12.gif")); //$NON-NLS-1$
+ down.addSelectionListener(this);
+ down.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsDown);
+ }
+
+
+
+ /**
+ * {@inheritDoc} Handles the events on one of the control buttons
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ * The event that occurred
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == add) {
+ addAction();
+ } else if (e.widget == remove) {
+ removeAction();
+ } else if (e.widget == addAll) {
+ addAllAction();
+ } else if (e.widget == removeAll) {
+ removeAllAction();
+ } else if (e.widget == up) {
+ upAction();
+ } else if (e.widget == down) {
+ downAction();
+ }
+ }
+
+ /**
+ * Handles the "Add" action
+ */
+ protected void addAction() {
+ Object[] elements = selector.getSelectedElements();
+ addElements(elements);
+ }
+
+ /**
+ * Handles the "Up" action
+ */
+ protected void upAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(currentSelection);
+ for (Object o : selection.toArray()) {
+ int oldIndex = list.indexOf(o);
+ if (oldIndex > 0) {
+ move(list, oldIndex, oldIndex - 1);
+ }
+ }
+
+ currentSelection.clear();
+ currentSelection.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Down" action
+ */
+ protected void downAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(currentSelection);
+
+ int maxIndex = list.size() - 1;
+
+ Object[] selectionArray = selection.toArray();
+ for (int i = selectionArray.length - 1; i >= 0; i--) {
+ Object o = selectionArray[i];
+ int oldIndex = list.indexOf(o);
+ if (oldIndex < maxIndex) {
+ move(list, oldIndex, oldIndex + 1);
+ }
+ }
+
+ currentSelection.clear();
+ currentSelection.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Moves an element from oldIndex to newIndex
+ *
+ * @param list
+ * The list in which to move the object
+ * @param oldIndex
+ * @param newIndex
+ */
+ protected void move(java.util.List<Object> list, int oldIndex, int newIndex) {
+ int size = list.size();
+
+ if (oldIndex < 0 || oldIndex >= size)
+ {
+ throw new IndexOutOfBoundsException("oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (newIndex < 0 || newIndex >= size)
+ {
+ throw new IndexOutOfBoundsException("newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ Object element = list.remove(oldIndex);
+ list.add(newIndex, element);
+ }
+
+ /**
+ * Handles the "Remove" action
+ */
+ protected void removeAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+ if (selection.isEmpty()) {
+ return;
+ }
+
+ for (Object element : selection.toArray()) {
+ currentSelection.remove(element);
+ }
+
+ selector.setSelectedElements(currentSelection.toArray());
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Remove all" action
+ */
+ protected void removeAllAction() {
+ currentSelection.clear();
+ selector.setSelectedElements(new Object[0]);
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Add All" action
+ */
+ protected void addAllAction() {
+ Object[] elements = selector.getAllElements();
+ addElements(elements);
+ }
+
+ /**
+ * Adds the specified elements to the currently selected elements (For
+ * "Add" and "Add all" actions)
+ *
+ * @param elements
+ * The elements to be added
+ */
+ protected void addElements(Object[] elements) {
+ if (elements != null) {
+ currentSelection.addAll(Arrays.asList(elements));
+ selectedElementsViewer.refresh();
+ }
+ }
+
+
+ /**
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ */
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing to do
+ }
+
+ public void setAdditionalButton(boolean withAdditionalButton, String messageButton, SelectionListener listener) {
+ this.withAdditionalButton = withAdditionalButton;
+ this.additionalButtonLabel = messageButton;
+ this.additionalButtonSelectionListener = listener;
+ }
+
+ /**
+ * Set the message displayed by the Editor
+ *
+ * @param string
+ * the message displayed by the editor
+ */
+ public void setMessage(String string) {
+ this.message = string;
+ }
+
+ /**
+ * Returns all selected elements
+ *
+ * @return
+ * all selected elements
+ */
+ public Collection<?> getSelectedElements() {
+ return currentSelection;
+ }
+
+
+ /**
+ * Returns the list of the elements to remove
+ *
+ * @return
+ * the list of the elements to remove
+ */
+ public java.util.List<Object> getElementToRemove() {
+ java.util.List<Object> removedObject = new ArrayList<Object>();
+ for (Object current : this.initialSelection) {
+ if (!getSelectedElements().contains(current)) {
+ removedObject.add(current);
+ }
+ }
+ return removedObject;
+ }
+
+ /**
+ * Returns the list of the elements to add
+ *
+ * @return
+ * the list of the elements to add
+ */
+ public java.util.List<Object> getElementToAdd() {
+ java.util.List<Object> addedObject = new ArrayList<Object>();
+ for (Object current : getSelectedElements()) {
+ if (!this.initialSelection.contains(current)) {
+ addedObject.add(current);
+ }
+ }
+ return addedObject;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionMenu.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionMenu.java
new file mode 100644
index 00000000000..22a624ecf77
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/SelectionMenu.java
@@ -0,0 +1,291 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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
+ * Shuai Li (CEA LIST) shuai.li@cea.fr - SelectionMenu#refresh method
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * A basic menu which proposes a list of choices.
+ *
+ * Implementation is based on a JFace TableViewer
+ *
+ * Typical usage: JDT-like Ctrl + Click (Navigation)
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class SelectionMenu {
+
+ private ILabelProvider labelProvider;
+
+ private IStructuredContentProvider contentProvider;
+
+ private Shell parentShell;
+
+ private Point location;
+
+ private Object input;
+
+ private Shell shell;
+
+ private TableViewer tableViewer;
+
+ private ISelectionChangedListener selectionChangedListener;
+
+ private List<ISelectionChangedListener> selectionChangedListeners;
+
+ private KeyListener keyListener;
+
+ private List<KeyListener> keyListeners;
+
+ private MouseTrackListener mouseTrackListener;
+
+ private List<MouseTrackListener> mouseTrackListeners;
+
+ public SelectionMenu(Shell parentShell) {
+ this(parentShell, parentShell.getDisplay().getCursorLocation());
+ }
+
+ public SelectionMenu(Shell parentShell, Object source) {
+ if (source instanceof TableViewer && parentShell != null) {
+ TableViewer tableViewer = (TableViewer) source;
+
+ // Get the cell's y position (we can't use the getCell(Point location) method)
+ int selectionIndex = tableViewer.getTable().getSelectionIndex();
+ int cellHeight = tableViewer.getTable().getItem(selectionIndex).getBounds().height;
+ int y = tableViewer.getTable().getShell().getLocation().y;
+ y += selectionIndex * cellHeight;
+
+ // Get the cell's x position and append by the table's width
+ //int width= tableViewer.getTable().getSize().x;
+ int width = tableViewer.getTable().getShell().getBounds().width;
+ int x = tableViewer.getTable().getShell().getLocation().x + width;
+
+ Point location = new Point(x, y);
+ init(parentShell, location, -1, 0);
+ return;
+ }
+
+ init(parentShell, parentShell.getDisplay().getCursorLocation(), 1, 1);
+ }
+
+ public SelectionMenu(Shell parentShell, Object source, Point cursorPosition) {
+ if (source instanceof Table && parentShell != null && cursorPosition != null) {
+ Table table = (Table) source;
+
+ TableItem item = table.getItem(cursorPosition);
+
+ if (item != null) {
+ int selectionIndex = 0;
+ for (Object tableItem : table.getItems()) {
+ if (tableItem.equals(item)) {
+ break;
+ }
+ selectionIndex++;
+ }
+
+ int cellHeight = item.getBounds().height;
+ int y = table.getShell().getLocation().y;
+ y += selectionIndex * cellHeight;
+
+ // Get the cell's x position and append by the table's width
+ //int width= tableViewer.getTable().getSize().x;
+ int width = table.getShell().getBounds().width;
+ int x = table.getShell().getLocation().x + width;
+
+ Point location = new Point(x, y);
+ init(parentShell, location, -1, 0);
+ return;
+ }
+ }
+
+ init(parentShell, parentShell.getDisplay().getCursorLocation(), 1, 1);
+ }
+
+ public SelectionMenu(Shell parentShell, Point location) {
+ init(parentShell, location, 1, 1);
+ }
+
+ protected void init(Shell parentShell, Point location, int xOffset, int yOffset) {
+ // Move the shell so that it doesn't open under the mouse
+ // The hovered element can still be selected
+ location.x += xOffset;
+ location.y += yOffset;
+
+ this.parentShell = parentShell;
+ this.location = location;
+ labelProvider = new LabelProvider();
+
+ selectionChangedListeners = new LinkedList<ISelectionChangedListener>();
+ selectionChangedListener = new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ for (ISelectionChangedListener listener : selectionChangedListeners) {
+ listener.selectionChanged(event);
+ }
+ }
+ };
+
+ keyListeners = new LinkedList<KeyListener>();
+ keyListener = new KeyListener() {
+ @Override
+ public void keyPressed(KeyEvent event) {
+ for (KeyListener listener : keyListeners) {
+ listener.keyPressed(event);
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event) {
+ for (KeyListener listener : keyListeners) {
+ listener.keyReleased(event);
+ }
+ }
+ };
+
+ mouseTrackListeners = new LinkedList<MouseTrackListener>();
+ mouseTrackListener = new MouseTrackListener() {
+ @Override
+ public void mouseEnter(MouseEvent event) {
+ for (MouseTrackListener mouseTrackListener : mouseTrackListeners) {
+ mouseTrackListener.mouseEnter(event);
+ }
+ }
+
+ @Override
+ public void mouseExit(MouseEvent event) {
+ for (MouseTrackListener mouseTrackListener : mouseTrackListeners) {
+ mouseTrackListener.mouseExit(event);
+ }
+ }
+
+ @Override
+ public void mouseHover(MouseEvent event) {
+ for (MouseTrackListener mouseTrackListener : mouseTrackListeners) {
+ mouseTrackListener.mouseHover(event);
+ }
+ }
+ };
+ }
+
+ public void open() {
+ // Shell background and background
+ shell = new Shell(parentShell, SWT.NONE);
+ shell.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
+ /*GridLayout gridLayout = new GridLayout(1, false);
+ gridLayout.marginWidth = 5;
+ gridLayout.marginHeight = 5;
+ shell.setLayout(gridLayout);*/
+ shell.setLayout(new GridLayout(1, false));
+
+ // TableViewer for menu items
+ tableViewer = new TableViewer(shell, SWT.NO_SCROLL);
+ tableViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ tableViewer.setContentProvider(contentProvider);
+ tableViewer.setLabelProvider(labelProvider);
+ ColumnViewerToolTipSupport.enableFor(tableViewer);
+ tableViewer.setInput(input);
+
+ // Listeners
+ tableViewer.addSelectionChangedListener(selectionChangedListener);
+ tableViewer.getTable().addKeyListener(keyListener);
+ tableViewer.getTable().addMouseTrackListener(mouseTrackListener);
+
+ // Open
+ shell.setLocation(location);
+ shell.pack();
+ shell.open();
+
+
+ }
+
+ public void refresh() {
+ tableViewer.refresh();
+ shell.pack();
+ }
+
+ public void dispose() {
+ if (tableViewer != null) {
+ tableViewer.removeSelectionChangedListener(selectionChangedListener);
+ }
+
+ if (tableViewer.getTable() != null) {
+ tableViewer.getTable().removeKeyListener(keyListener);
+ }
+
+ if (shell != null) {
+ shell.dispose();
+ }
+ }
+
+ public void setContentProvider(IStructuredContentProvider provider) {
+ this.contentProvider = provider;
+ }
+
+ public void setInput(Object input) {
+ this.input = input;
+ }
+
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ }
+
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ this.selectionChangedListeners.add(listener);
+ }
+
+ public void addKeyListener(KeyListener listener) {
+ this.keyListeners.add(listener);
+ }
+
+ public void addMouseTrackListener(MouseTrackListener listener) {
+ this.mouseTrackListeners.add(listener);
+ }
+
+ public Shell getShell() {
+ return shell;
+ }
+
+ public void setShell(Shell shell) {
+ this.shell = shell;
+ }
+
+ public Shell getParentShell() {
+ return parentShell;
+ }
+
+ public TableViewer getTableViewer() {
+ return tableViewer;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringCombo.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringCombo.java
new file mode 100644
index 00000000000..6234e5db3b6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringCombo.java
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ * Christian W. Damus (CEA) - bug 436072
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net- Bug 446865
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+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.infra.tools.databinding.AggregatedObservable;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Widget for editing a String with an editable combo.
+ * The combo proposes a set of default values.
+ *
+ * @author Camille Letavernier
+ */
+public class StringCombo extends ReferenceCombo {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style used.
+ */
+ public StringCombo(final Composite parent, final int style) {
+ super(parent, style);
+ combo.setEditable(true);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style used.
+ * @param label
+ * The initial label.
+ */
+ public StringCombo(final Composite parent, final int style, final String label) {
+ super(parent, style, label);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#getEditableType()
+ */
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ /**
+ * Sets the content provider for this combo. The Content provider should
+ * specify the objects that can be referred by this property
+ *
+ * @param provider
+ * The provider.
+ */
+ @Override
+ public void setContentProvider(IStaticContentProvider provider) {
+ if (provider != null) {
+ contentProvider = new EncapsulatedContentProvider(provider);
+ viewer.setContentProvider(contentProvider);
+ viewer.setInput(""); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#getObservableValue()
+ */
+ @Override
+ protected IObservableValue getObservableValue() {
+ return new CComboObservableValue();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#getValue()
+ */
+ @Override
+ public String getValue() {
+ // See Bug 359835 : The ComboViewer doesn't support custom values
+ // We can't rely on the ComboViewer#getSelection() method
+ return combo.getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#setValue(java.lang.Object)
+ */
+ @Override
+ public void setValue(Object value) {
+ // See Bug 359835 : The ComboViewer doesn't support custom values
+ // We can't rely on the ComboViewer#setSelection() method
+ if (value instanceof String) {
+ combo.setText((String) value);
+ } else {
+ combo.setText(""); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Updates the controls display.
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.ReferenceCombo#updateControls()
+ */
+ @Override
+ protected void updateControls() {
+ // See Bug 359835 : The ComboViewer doesn't support custom values
+ String value = getValue();
+ super.updateControls();
+ setValue(value);
+ }
+
+ class CComboObservableValue extends AbstractObservableValue implements SelectionListener, KeyListener, FocusListener {
+
+ private String previousValue;
+
+ public CComboObservableValue() {
+ previousValue = combo.getText();
+ combo.addSelectionListener(this); // Selection change
+ combo.addKeyListener(this); // Enter pressed
+ combo.addFocusListener(this); // Focus lost
+ }
+
+ @Override
+ public Object getValueType() {
+ return String.class;
+ }
+
+ @Override
+ protected String doGetValue() {
+ return combo.getText();
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ if (modelProperty instanceof AggregatedObservable && ((AggregatedObservable) modelProperty).hasDifferentValues()) {
+ combo.setText(UnchangedObject.instance.toString());
+ } else if (value instanceof String) {
+ // This is the new baseline value (coming from the model) against which to compare a future edit by the user
+ previousValue = (String) value;
+ combo.setText(previousValue);
+ }
+ }
+
+ // Enter pressed
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if ((e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) && e.stateMask == SWT.NONE) {
+ maybeFireChange();
+ e.doit = false; // Stops the propagation of the event
+ }
+ }
+
+ // Selection change
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ maybeFireChange();
+ }
+
+ // Focus lost
+ @Override
+ public void focusLost(FocusEvent e) {
+ maybeFireChange();
+ }
+
+ void maybeFireChange() {
+ // Only report a change if there is actually a change, otherwise we get a no-op command that dirties the editor
+ final String currentValue = doGetValue();
+ if ((currentValue == null) ? previousValue != null : !currentValue.equals(previousValue)) {
+ doFireChange();
+ }
+ }
+
+ private void doFireChange() {
+ final String oldValue = previousValue;
+ final String currentValue = previousValue = doGetValue();
+ fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return currentValue;
+ }
+ });
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // Nothing
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditor.java
new file mode 100644
index 00000000000..1b3cdb80c4f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditor.java
@@ -0,0 +1,480 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.papyrus.infra.widgets.databinding.TextObservableValue;
+import org.eclipse.papyrus.infra.widgets.selectors.StringSelector;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A Property Editor representing a single-line or multi-line String value as a
+ * Text. This editor's content is validated when the focus is lost, or, if the
+ * editor is single-line, when the Carriage Return is pressed. For a multi-line
+ * editor, ctrl+enter will also validate the editor's content.
+ *
+ * @see SWT#MULTI
+ *
+ * @author Camille Letavernier
+ */
+public class StringEditor extends AbstractValueEditor implements KeyListener, ModifyListener {
+
+ /**
+ * The text box for editing this editor's value
+ */
+ protected final Text text;
+
+ private int delay = 600;
+
+ private boolean validateOnDelay = false;
+
+ private Timer timer;
+
+ private TimerTask currentValidateTask;
+
+ private TimerTask changeColorTask;
+
+ private final static int DEFAULT_HEIGHT_HINT = 55;
+
+ private final static int DEFAULT_WIDTH_HINT = 100;
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ */
+ public StringEditor(Composite parent, int style) {
+ this(parent, style, null, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT);
+
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ */
+ public StringEditor(Composite parent, int style, String label) {
+ this(parent, style, label, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param heighHint
+ * Height hint of the text area in multiline mode
+ * @param widthHint
+ * Width hint of the text area in multiline mode
+ */
+ public StringEditor(Composite parent, int style, int heighHint, int widthHint) {
+ this(parent, style, null, heighHint, widthHint);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ * @param heighHint
+ * Height hint of the text area in multiline mode
+ * @param widthHint
+ * Width hint of the text area in multiline mode
+ */
+ public StringEditor(Composite parent, int style, String label, int heighHint, int widthHint) {
+ super(parent, label);
+
+ GridData data = getDefaultLayoutData();
+ data.grabExcessVerticalSpace = true;
+ data.grabExcessHorizontalSpace = true;
+ data.verticalAlignment = SWT.FILL;
+
+ if ((style & SWT.MULTI) != 0) {
+ data.minimumHeight = heighHint;
+ data.minimumWidth = widthHint;
+ style = style | SWT.V_SCROLL;
+ }
+
+ text = factory.createText(this, null, style);
+ text.setLayoutData(data);
+
+ if (label != null) {
+ super.label.setLayoutData(getLabelLayoutData());
+
+ }
+ text.addKeyListener(this);
+ text.addModifyListener(this);
+ setCommitOnFocusLost(text);
+ controlDecoration = new ControlDecoration(text, SWT.LEFT | SWT.TOP);
+ controlDecoration.hide();
+ data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ pack();
+
+ }
+
+ @Override
+ protected GridData getLabelLayoutData() {
+ GridData result = super.getLabelLayoutData();
+ if (text != null) {
+ if ((text.getStyle() & SWT.MULTI) != 0) {
+ result.verticalAlignment = SWT.BEGINNING;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Ignored
+ */
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // Nothing
+
+
+
+ }
+
+ /**
+ * Validates this editor when one of the following events occur : - CR
+ * released - Keypad CR released - Ctrl + [CR | Keypad CR] released
+ *
+ * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ *
+ * @param e
+ */
+ // TODO : we should prevent the \n from being written when validating the
+ // multi-line field with Ctrl + CR
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // We listen on Carriage Return or Ctrl+ Carriage return, depending on
+ // whether the editor is single- or multi-line
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+ if ((text.getStyle() & SWT.MULTI) == 0) { // Single-line : Enter
+ if (e.stateMask == SWT.NONE) {
+ notifyChange();
+ }
+ } else { // Multi-line : Ctrl+Enter
+ if (e.stateMask == SWT.CTRL) {
+ String str = text.getText();
+ if (str.endsWith(StringSelector.LINE_SEPARATOR)) {
+ int newLength = str.length() - StringSelector.LINE_SEPARATOR.length();
+ text.setText(str.substring(0, newLength));
+ text.setSelection(newLength);
+ }
+ notifyChange();
+ }
+ }
+ }
+
+
+ }
+
+ @Override
+ public void setModelObservable(IObservableValue observable) {
+ setWidgetObservable(new TextObservableValue(text, observable, SWT.FocusOut), true);
+ super.setModelObservable(observable);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ return text.getText();
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ text.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !text.isEnabled();
+ }
+
+ protected void notifyChange() {
+
+ text.notifyListeners(SWT.FocusOut, new Event());
+ commit();
+ changeColorField();
+ }
+
+ @Override
+ public void setToolTipText(String tooltip) {
+ text.setToolTipText(tooltip);
+ super.setLabelToolTipText(tooltip);
+ }
+
+ /**
+ * Sets the current text value for this editor
+ *
+ * @param value
+ */
+ public void setValue(Object value) {
+ if (value instanceof String) {
+ this.text.setText((String) value);
+ } else {
+ this.text.setText(""); //$NON-NLS-1$;
+ }
+ }
+
+ /**
+ * Indicates that this editor should be automatically validated after a
+ * timer.
+ *
+ * @param validateOnDelay
+ */
+ public void setValidateOnDelay(boolean validateOnDelay) {
+ this.validateOnDelay = validateOnDelay;
+
+ if (validateOnDelay) {
+ text.addModifyListener(this);
+ } else {
+ text.removeModifyListener(this);
+ cancelCurrentTask();
+ }
+ }
+
+ /**
+ * Indicates that this editor should be automatically validated after the
+ * given timer
+ *
+ * @param millis
+ * The delay after which the editor should be automatically
+ * validated, in milliseconds. The default is 600ms
+ */
+ public void setValidateOnDelay(int millis) {
+ this.delay = millis;
+ setValidateOnDelay(true);
+ if (delay == 0) {
+ cancelCurrentTask();
+ }
+ }
+
+ private void cancelCurrentTask() {
+ if (currentValidateTask != null) {
+ currentValidateTask.cancel();
+ currentValidateTask = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+
+ // SWT Thread
+ if (validateOnDelay) {
+ if (delay == 0) {
+ commit(); // Direct commit on edition, to avoid creating useless
+ // threads
+
+ return;
+ }
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ currentValidateTask = new TimerTask() {
+
+ // Timer thread
+ @Override
+ public void run() {
+ StringEditor.this.getDisplay().syncExec(new Runnable() {
+
+ // SWT Thread
+ @Override
+ public void run() {
+
+ commit();
+ }
+ });
+ }
+ };
+ timer.schedule(currentValidateTask, delay);
+ }
+ if (targetValidator != null) {
+ IStatus status = targetValidator.validate(text.getText());
+ updateStatus(status);
+ }
+ if (modelValidator != null) {
+ IStatus status = modelValidator.validate(text.getText());
+ updateStatus(status);
+ if (binding == null) {
+ update();
+ }
+ }
+
+ if (modelProperty != null) { // Bug 433169: The widget may be used without an Observable Value (setValue + getValue)
+ if (modelProperty.getValue() != null) {
+ if (!isReadOnly() && !modelProperty.getValue().toString().equals(text.getText())) {
+ text.setBackground(EDIT);
+ } else {
+ text.setBackground(DEFAULT);
+ }
+ } else {
+ if (text.getText().equals("")) {
+ text.setBackground(DEFAULT);
+ } else {
+ text.setBackground(EDIT);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ cancelCurrentTask();
+ cancelChangeColorTask();
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ super.dispose();
+ }
+
+ public Text getText() {
+ return text;
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+
+ }
+
+ @Override
+ public void changeColorField() {
+ if (binding != null) {
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelChangeColorTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ if (StringEditor.this.isDisposed()) {
+ return;
+ }
+ StringEditor.this.getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ text.setBackground(DEFAULT);
+ text.update();
+ }
+ });
+ }
+ };
+ if (errorBinding) {
+ text.setBackground(ERROR);
+ text.update();
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ text.setBackground(VALID);
+ text.update();
+ break;
+ case IStatus.ERROR:
+ text.setBackground(ERROR);
+ text.update();
+ break;
+
+ }
+ }
+ }
+ }
+
+ private void cancelChangeColorTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ changeColorTask = null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditorWithCompletionWrapper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditorWithCompletionWrapper.java
new file mode 100644
index 00000000000..7de49d963cc
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringEditorWithCompletionWrapper.java
@@ -0,0 +1,200 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.contentassist.ContentAssistEvent;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.ICompletionListener;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter;
+import org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Vincent Lorenzo
+ *
+ * This class allows to build a StyledText widget allowing the completion
+ *
+ */
+public class StringEditorWithCompletionWrapper implements ISetPapyrusConverter{
+
+ /**
+ * the parser used to convert object to string and string to object
+ */
+ public IPapyrusConverter parser;
+
+ /**
+ * boolean indicating if the content assist popup is opened
+ */
+ private boolean delayedIsOpen = false;
+
+ /**
+ * the text viewer
+ */
+ private TextViewer textViewer;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * the parent to use to create the TextWidget
+ * @param helper
+ * the helper to use to find the elements by their name
+ */
+ public StringEditorWithCompletionWrapper(Composite parent, IPapyrusConverter parser) {
+ setPapyrusConverter(parser);
+ buildControls(parent, SWT.NONE);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * the parent to use to create the TextWidget
+ * @param helper
+ * the helper to use to find the elements by their name
+ */
+ public StringEditorWithCompletionWrapper(Composite parent, int style, IPapyrusConverter parser) {
+ setPapyrusConverter(parser);
+ buildControls(parent, style);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * the parent to use to create the TextWidget
+ * @param helper
+ * the helper to use to find the elements by their name
+ */
+ public StringEditorWithCompletionWrapper(Composite parent, int style) {
+ buildControls(parent, style);
+ }
+
+
+ /**
+ *
+ * @return
+ * the text viewer used
+ */
+ public TextViewer getTextViewer() {
+ return this.textViewer;
+ }
+
+ /**
+ *
+ * @return
+ * the styled text used or <code>null</code>
+ */
+ public StyledText getTextWidget() {
+ if (this.textViewer != null) {
+ return this.textViewer.getTextWidget();
+ }
+ return null;
+ }
+
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the content assist is currently opened
+ */
+ public boolean isContentAssistOpened() {
+ return delayedIsOpen;
+ }
+
+ private ContentAssistant assistant;
+
+ private IContentAssistProcessor processor;
+
+ private void buildControls(Composite parent, int style) {
+ // setLayout(new FillLayout());
+ textViewer = new TextViewer(parent, SWT.SINGLE | SWT.V_SCROLL | style);
+
+ textViewer.setDocument(new Document());
+
+ this.assistant = new ContentAssistant();
+
+
+ if (parser != null) {
+ this.processor = parser.getCompletionProcessor(null);
+ assistant.setContentAssistProcessor(this.processor, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ assistant.install(textViewer);
+ assistant.addCompletionListener(new ICompletionListener() {
+
+ @Override
+ public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) {
+
+ }
+
+ @Override
+ public void assistSessionStarted(ContentAssistEvent event) {
+ // reset open status asynchronously.
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ delayedIsOpen = true;
+ }
+ });
+ }
+
+ @Override
+ public void assistSessionEnded(ContentAssistEvent event) {
+ // reset open status asynchronously.
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ delayedIsOpen = false;
+ }
+ });
+
+ }
+ });
+ textViewer.getControl().addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (SWT.CTRL == e.stateMask && SWT.SPACE == e.character) {
+ assistant.showPossibleCompletions();
+ }
+ }
+ });
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.util.ISetPapyrusConverter#setPapyrusConverter(org.eclipse.papyrus.infra.widgets.util.IPapyrusConverter)
+ *
+ * @param parser
+ */
+ @Override
+ public void setPapyrusConverter(IPapyrusConverter parser) {
+ this.parser = parser;
+ if (parser != null && assistant!=null && processor==null) {
+ this.processor = parser.getCompletionProcessor(null);
+ assistant.setContentAssistProcessor(this.processor, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringFileSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringFileSelector.java
new file mode 100644
index 00000000000..941c2711c9e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringFileSelector.java
@@ -0,0 +1,244 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
+import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider;
+import org.eclipse.papyrus.infra.widgets.util.FileUtil;
+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.FileDialog;
+
+/**
+ * A Widget for editing Strings with File paths
+ * The file paths may be absolute (FileSystem paths) or relative to the workspace (Workspace paths)
+ *
+ * @author Camille Letavernier
+ */
+public class StringFileSelector extends StringEditor {
+
+ private Button browse;
+
+ private Button browseWorkspace;
+
+ private List<String> filterNames;
+
+ private List<String> filterExtensions;
+
+ private boolean allowWorkspace = true, allowFileSystem = true;
+
+ private boolean readOnly = false;
+
+ public StringFileSelector(Composite parent, int style) {
+ super(parent, style);
+ ((GridLayout) getLayout()).numColumns = 5;
+
+ browse = factory.createButton(this, Messages.StringFileSelector_Browse, SWT.PUSH);
+ browse.setLayoutData(new GridData());
+ browseWorkspace = factory.createButton(this, Messages.StringFileSelector_BrowseWorkspace, SWT.PUSH);
+ browseWorkspace.setLayoutData(new GridData());
+
+ filterNames = new LinkedList<String>();
+ filterExtensions = new LinkedList<String>();
+
+ browse.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ File file = FileUtil.getFile(text.getText());
+
+ FileDialog dialog = new FileDialog(getShell());
+ if (labelText != null) {
+ dialog.setText(labelText);
+ }
+ dialog.setFileName(file.getAbsolutePath());
+ dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()]));
+ dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()]));
+ String result = dialog.open();
+ if (result == null) { // Cancel
+ return;
+ }
+ setResult(result);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ });
+
+ browseWorkspace.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ LabelProviderService labelProviderService = new LabelProviderServiceImpl();
+ try {
+ labelProviderService.startService();
+ } catch (ServiceException ex) {
+ Activator.log.error(ex);
+ }
+
+ ILabelProvider labelProvider = labelProviderService.getLabelProvider();
+
+ IFile currentFile = FileUtil.getIFile(text.getText());
+
+ TreeSelectorDialog dialog = new TreeSelectorDialog(getShell());
+ if (labelText != null) {
+ dialog.setTitle(labelText);
+ }
+
+ WorkspaceContentProvider contentProvider = new WorkspaceContentProvider();
+
+ if (!(filterExtensions.isEmpty() || filterNames.isEmpty())) {
+ // The filters have been defined
+ contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); // Reset the default filters
+
+ // Use our own filters
+ for (int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) {
+ contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i));
+ }
+ }
+
+ dialog.setContentProvider(contentProvider);
+ dialog.setLabelProvider(labelProvider);
+
+
+ if (currentFile != null && currentFile.exists()) {
+ dialog.setInitialSelections(new IFile[] { currentFile });
+ }
+
+ int code = dialog.open();
+ if (code == Window.OK) {
+ Object[] result = dialog.getResult();
+ if (result.length > 0) {
+ Object file = result[0];
+ if (file instanceof IFile) {
+ setResult((IFile) file);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ });
+ }
+
+ protected void setResult(IFile file) {
+ text.setText(file.getFullPath().toString());
+ notifyChange();
+ }
+
+ protected void setResult(File file) {
+ text.setText(file.getAbsolutePath());
+ notifyChange();
+ }
+
+ protected void setResult(String path) {
+ text.setText(path);
+ notifyChange();
+ }
+
+ public void setFilters(String[] filterExtensions, String[] filterNames) {
+ if (filterExtensions.length != filterNames.length) {
+ // This is a simple warning. Only valid filters will be retained.
+ Activator.log.warn(Messages.StringFileSelector_0);
+ }
+
+ setFilterNames(getFilterLabels(filterNames, filterExtensions));
+ setFilterExtensions(filterExtensions);
+ }
+
+ protected String[] getFilterLabels(String[] filterNames, String[] filterExtensions) {
+ int size = Math.min(filterNames.length, filterExtensions.length);
+ String[] filters = new String[size];
+ for (int i = 0; i < size; i++) {
+ filters[i] = filterNames[i] + " (" + filterExtensions[i] + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return filters;
+ }
+
+ public void setFilterExtensions(String[] filterExtensions) {
+ this.filterExtensions = Arrays.asList(filterExtensions);
+ }
+
+ public void setFilterNames(String[] filterNames) {
+ this.filterNames = Arrays.asList(filterNames);
+ }
+
+ public void addFilteredExtension(String filteredExtension, String filterName) {
+ if (filteredExtension != null) {
+ if (filterName == null) {
+ filterName = filteredExtension;
+ }
+
+ filterExtensions.add(filteredExtension);
+ filterNames.add(filterName);
+ }
+ }
+
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ super.setReadOnly(readOnly);
+ this.readOnly = readOnly;
+ updateButtons();
+ }
+
+ public void setAllowWorkspace(boolean allowWorkspace) {
+ this.allowWorkspace = allowWorkspace;
+ updateButtons();
+ }
+
+ public void setAllowFileSystem(boolean allowFileSystem) {
+
+ this.allowFileSystem = allowFileSystem;
+ updateButtons();
+ }
+
+ private void updateButtons() {
+ boolean enableWorkspace = !readOnly && allowWorkspace;
+ boolean enableFileSystem = !readOnly && allowFileSystem;
+ // ((GridData)browseWorkspace.getLayoutData()).exclude = !allowWorkspace;
+ // ((GridData)browse.getLayoutData()).exclude = !allowFileSystem;
+ browseWorkspace.setEnabled(enableWorkspace);
+ browse.setEnabled(enableFileSystem);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringLabel.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringLabel.java
new file mode 100644
index 00000000000..28b1e0bd892
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringLabel.java
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Read only widget to display Strings as a CLabel.
+ * May also be used to display an Object with an ILabelProvider
+ *
+ * @author Camille Letavernier
+ */
+public class StringLabel extends AbstractValueEditor implements IChangeListener {
+
+ private final CLabel valueLabel;
+
+ private ILabelProvider labelProvider;
+
+ private Object value;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The Composite widget in which this editor is created
+ * @param style
+ * The style to be applied to this editor's CLabel
+ */
+ public StringLabel(final Composite parent, final int style) {
+ super(parent, style);
+ this.valueLabel = factory.createCLabel(this, "", style); //$NON-NLS-1$
+ this.valueLabel.setLayoutData(getDefaultLayoutData());
+ this.labelProvider = new LabelProvider();
+ }
+
+ /**
+ * @return
+ * The CLabel used to display this editor's value
+ */
+ public CLabel getValueLabel() {
+ return this.valueLabel;
+ }
+
+ /**
+ * Sets the label provider for this editor. Useful when the value is not a
+ * String
+ *
+ * @param labelProvider
+ * The Label provider used to display the current value
+ */
+ public void setLabelProvider(final ILabelProvider labelProvider) {
+ if (labelProvider == null) {
+ return;
+ }
+
+ this.labelProvider = labelProvider;
+ if (this.binding != null) {
+ this.binding.updateModelToTarget();
+ }
+ }
+
+ @Override
+ public void doBinding() {
+ // We don't do a real databinding here
+ this.modelProperty.addChangeListener(this);
+ valueLabel.addDisposeListener(this);
+ updateLabel();
+ }
+
+ /**
+ * Updates the CLabel's display
+ */
+ protected void updateLabel() {
+ if (valueLabel.isDisposed()) {
+ Activator.log.warn("Widget is disposed"); //$NON-NLS-1$
+ return;
+ }
+
+ Object value = getValue();
+
+ String text = this.labelProvider.getText(value);
+ Image image = this.labelProvider.getImage(value);
+
+ this.valueLabel.setText(text);
+ this.valueLabel.setImage(image);
+ }
+
+ @Override
+ public Object getValue() {
+ if (modelProperty != null) {
+ return modelProperty.getValue();
+ }
+ return value;
+ }
+
+ public void setValue(Object value) {
+ if (modelProperty != null) {
+ modelProperty.setValue(value);
+ }
+ this.value = value;
+
+ updateLabel();
+ }
+
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ @Override
+ public void setReadOnly(final boolean readOnly) {
+ // Nothing
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !this.valueLabel.isEnabled();
+ }
+
+ @Override
+ public void setToolTipText(final String text) {
+ this.valueLabel.setToolTipText(text);
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ updateLabel();
+ }
+
+ @Override
+ public void dispose() {
+ if (this.modelProperty != null) {
+ this.modelProperty.removeChangeListener(this);
+ }
+ super.dispose();
+ }
+
+ @Override
+ public void refreshValue() {
+ updateLabel();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringMask.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringMask.java
new file mode 100644
index 00000000000..7ab1b6f7bc1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringMask.java
@@ -0,0 +1,222 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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.infra.widgets.editors;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+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;
+
+/**
+ * A Widget to manipulate a list of values.
+ *
+ * The widget is configured with a Map of (String, String) entries (Key -> Label).
+ * It returns the list of selected keys.
+ *
+ * @author Camille Letavernier
+ */
+public class StringMask extends AbstractListEditor implements SelectionListener, IChangeListener, DisposeListener {
+
+ private Button[] checkboxes;
+
+ private Collection<String> currentValue;
+
+ private final Composite checkboxContainer;
+
+ private boolean refreshCheckboxes = true;
+
+ private boolean isReadOnly = false;
+
+ public static final String DATA_KEY = "stringValue"; //$NON-NLS-1$
+
+ public StringMask(final Composite parent, final int style) {
+ super(parent, style);
+ checkboxContainer = new Composite(this, style);
+ checkboxContainer.setLayoutData(getDefaultLayoutData());
+ checkboxContainer.setLayout(new GridLayout(2, true));
+ checkboxContainer.addDisposeListener(this);
+ }
+
+ @Override
+ protected GridData getLabelLayoutData() {
+ GridData data = super.getLabelLayoutData();
+ data.verticalAlignment = SWT.BEGINNING;
+ return data;
+ }
+
+ public Collection<String> getValue() {
+ Set<String> values = new HashSet<String>();
+ for (Button button : checkboxes) {
+ if (button.getSelection()) {
+ String value = (String) button.getData(DATA_KEY);
+ values.add(value);
+ }
+ }
+ return values;
+ }
+
+ @Override
+ public void dispose() {
+ if (modelProperty != null) {
+ modelProperty.removeChangeListener(this);
+ }
+ super.dispose();
+ }
+
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ @Override
+ public void setReadOnly(final boolean readOnly) {
+ this.isReadOnly = readOnly;
+ for (Button button : checkboxes) {
+ button.setEnabled(!readOnly);
+ }
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public void setMasks(final Map<String, String> values) {
+ if (checkboxes != null) {
+ disposeCheckboxes();
+ }
+
+ checkboxes = new Button[values.size()];
+
+ int i = 0;
+ for (Entry<String, String> mask : values.entrySet()) {
+ String stringValue = mask.getKey();
+ String label = mask.getValue();
+
+ checkboxes[i] = new Button(checkboxContainer, SWT.CHECK);
+ checkboxes[i].setText(label);
+ checkboxes[i].setData(DATA_KEY, stringValue);
+ checkboxes[i].addSelectionListener(this);
+ checkboxes[i].setToolTipText(stringValue);
+ i++;
+ }
+ }
+
+ protected void disposeCheckboxes() {
+ for (Button button : checkboxes) {
+ button.removeSelectionListener(this);
+ button.dispose();
+ }
+ }
+
+ public void setNumColumns(final int numColumns) {
+ ((GridLayout) checkboxContainer.getLayout()).numColumns = numColumns;
+ checkboxContainer.layout();
+ layout();
+ }
+
+ @Override
+ public void doBinding() {
+ // We don't do a real databinding here
+ modelProperty.addChangeListener(this);
+
+ refreshCheckboxes();
+ }
+
+ protected void refreshCheckboxes() {
+ if (!refreshCheckboxes) {
+ return;
+ }
+
+ Collection<String> values = getCurrentValue();
+ for (Button button : checkboxes) {
+ String value = (String) button.getData(DATA_KEY);
+ button.setSelection(values.contains(value));
+ }
+ }
+
+ @Override
+ public void setToolTipText(final String text) {
+ super.setLabelToolTipText(text);
+ }
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ Button button = (Button) e.widget;
+ String value = (String) button.getData(DATA_KEY);
+ Collection<String> values = new HashSet<String>(getCurrentValue());
+ if (button.getSelection()) {
+ values.add(value);
+ } else {
+ values.remove(value);
+ }
+ setCurrentValue(values);
+ }
+
+ protected void setCurrentValue(final Collection<String> values) {
+ if (modelProperty != null) {
+ refreshCheckboxes = false;
+ modelProperty.clear();
+ modelProperty.addAll(values);
+ refreshCheckboxes = true;
+ }
+ currentValue = values;
+
+ commit();
+ }
+
+ protected Collection<String> getCurrentValue() {
+ if (modelProperty != null) {
+ return modelProperty;
+ } else {
+ return currentValue;
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(final SelectionEvent e) {
+ // Nothing
+ }
+
+ public int getNumColumns() {
+ return ((GridLayout) checkboxContainer.getLayout()).numColumns;
+ }
+
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ refreshCheckboxes();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#changeColorField()
+ *
+ */
+
+ @Override
+ public void changeColorField() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java
new file mode 100644
index 00000000000..9206ebbec79
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java
@@ -0,0 +1,744 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Nicolas FAUVERGUE (ALL4TEC� nicolas.fauvergue@all4tec.net - Bug 459747
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.databinding.StyledTextReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.validator.AbstractValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+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.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * An editor representing a single reference as a String Editor. A filtered selection
+ * dialog is used to edit the value. Also offers support for unsetting the
+ * value. This Editor needs a ContentProvider, and may use an optional
+ * LabelProvider, describing the objects that can be referred by this property
+ *
+ * @author Vincent Lorenzo
+ *
+ * Duplicated code from {@link ReferenceDialog}, replacing CLabel by {@link StyledTextStringEditor}
+ *
+ */
+public class StyledTextReferenceDialog extends AbstractReferenceDialog implements SelectionListener {
+
+ /**
+ * The styled text displaying the current value
+ */
+ protected final StyledTextStringEditor styledTextStringEditor;
+
+ /**
+ * The Button used to browse the available values
+ */
+ protected Button browseValuesButton;
+
+ /**
+ * The Button used to create a new instance
+ */
+ protected Button createInstanceButton;
+
+ /**
+ * The Button used to edit the current object
+ */
+ protected Button editInstanceButton;
+
+ /**
+ * The Button used to unset the current value
+ */
+ protected Button unsetButton;
+
+ /**
+ * The label provider used to display the values in both the label and the
+ * selection dialog
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The content provider, providing the different possible values for the
+ * input object
+ */
+ protected IStaticContentProvider contentProvider;
+
+ /**
+ * The dialog used to select the value
+ */
+ protected final ITreeSelectorDialog dialog;
+
+ /**
+ * The current value for this editor
+ */
+ protected Object value;
+
+ /**
+ * The factory used to create or edit objects directly from this editor
+ */
+ protected ReferenceValueFactory valueFactory;
+
+ /**
+ * Boolean to detect direct creation.
+ */
+ private boolean directCreation;
+
+ /**
+ * Determinate if an error occurred.
+ */
+ protected boolean error = false;
+
+ /**
+ * The timer.
+ */
+ private Timer timer;
+
+ /**
+ * The timer tack for the change color.
+ */
+ private TimerTask changeColorTask;
+
+ /**
+ * Determinate if an edit occurred.
+ */
+ private boolean edit = false;
+
+ /**
+ * Constructs a new ReferenceDialog in the given parent Composite. The style
+ * will be applied to the syled text displaying the current value.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style of the styled text.
+ */
+ public StyledTextReferenceDialog(final Composite parent, final int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ * Constructs a new ReferenceDialog in the given parent Composite. The style will be applied to the styled text displaying the current value. This constructor manage the value validator.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style of the styled text.
+ * @param targetValidator
+ * The validator used for the styled text.
+ */
+ public StyledTextReferenceDialog(final Composite parent, final int style, final AbstractValidator targetValidator) {
+ super(parent, style);
+ this.targetValidator = targetValidator;
+ GridData gridData = getDefaultLayoutData();
+
+ styledTextStringEditor = createStyledTextStringEditor(this, null, factory.getBorderStyle() | style);
+ styledTextStringEditor.setLayoutData(gridData);
+ styledTextStringEditor.addMouseListener(new MouseListener() {
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ editAction(); // TODO : Try to determine whether the double
+ // click should call the edit, create or browse action
+ // e.g. if the value is null, try to browse. If we cannot
+ // browse, try to create an instance.
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ // Nothing
+ }
+
+ });
+
+ dialog = createDialog(parent.getShell());
+
+ createButtons();
+ updateControls();
+ controlDecoration = new ControlDecoration(styledTextStringEditor, SWT.TOP | SWT.LEFT);
+
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ }
+
+ /**
+ * This allow to create the styled text editor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param initialValue
+ * The initial value of the styled text.
+ * @param style
+ * The style of the styled text.
+ * @return The created {@link StyledTextStringEditor}.
+ */
+ protected StyledTextStringEditor createStyledTextStringEditor(final Composite parent, final String initialValue, final int style) {
+ StyledTextStringEditor editor = new StyledTextStringEditor(parent, style, targetValidator);
+ editor.setValue(initialValue);
+ return editor;
+ }
+
+ /**
+ * This allow to create the dialog.
+ *
+ * @param shell
+ * The current shell.
+ * @return The created {@link ITreeSelectorDialog}.
+ */
+ protected ITreeSelectorDialog createDialog(final Shell shell) {
+ return new TreeSelectorDialog(shell);
+ }
+
+ /**
+ * This allow to create the buttons of the reference dialog (browse, create, edit and unset).
+ */
+ protected void createButtons() {
+ ((GridLayout) getLayout()).numColumns += 4;
+
+ browseValuesButton = factory.createButton(this, null, SWT.PUSH);
+ browseValuesButton.setImage(Activator.getDefault().getImage("/icons/browse_12x12.gif")); //$NON-NLS-1$
+ browseValuesButton.setToolTipText(Messages.ReferenceDialog_EditValue);
+ browseValuesButton.addSelectionListener(this);
+
+ createInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ createInstanceButton.setImage(Activator.getDefault().getImage("/icons/Add_12x12.gif")); //$NON-NLS-1$
+ createInstanceButton.setToolTipText(Messages.ReferenceDialog_CreateANewObject);
+ createInstanceButton.addSelectionListener(this);
+
+ editInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ editInstanceButton.setImage(Activator.getDefault().getImage("/icons/Edit_12x12.gif")); //$NON-NLS-1$
+ editInstanceButton.setToolTipText(Messages.ReferenceDialog_EditTheCurrentValue);
+ editInstanceButton.addSelectionListener(this);
+
+ unsetButton = factory.createButton(this, null, SWT.PUSH);
+ unsetButton.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ unsetButton.setToolTipText(Messages.ReferenceDialog_UnsetValue);
+ unsetButton.addSelectionListener(this);
+ }
+
+ /**
+ * The action executed when the "browse" button is selected Choose a value
+ * from a selection of already created objects
+ */
+ protected void browseAction() {
+ setInitialSelection(Collections.singletonList(getValue()));
+ int result = dialog.open();
+ if (result == Window.OK) {
+ Object[] newValue = dialog.getResult();
+ if (newValue == null) {
+ return;
+ }
+
+ if (newValue.length == 0) {
+ setValue(null);
+ } else {
+ Object value = newValue[0];
+ if (contentProvider instanceof IAdaptableContentProvider) {
+
+ value = ((IAdaptableContentProvider) contentProvider).getAdaptedValue(value);
+ }
+ setValue(value);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+ }
+ }
+
+ /**
+ * The action executed when the "create" button is selected Create a new
+ * instance and assign it to this reference
+ */
+ protected void createAction() {
+ if (valueFactory != null && valueFactory.canCreateObject()) {
+ final Object context = getContextElement();
+ getOperationExecutor(context).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object value = valueFactory.createObject(createInstanceButton, context);
+ if (value == null) {
+ // Cancel the operation
+ throw new OperationCanceledException();
+ }
+ Collection<Object> validatedObjects = valueFactory.validateObjects(Collections.singleton(value));
+ if (!validatedObjects.isEmpty()) {
+ final Object newValue = validatedObjects.iterator().next();
+ setValue(newValue);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+ }
+ }, NLS.bind(Messages.ReferenceDialog_setOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "edit" button is selected Edits the object
+ * that is currently selected
+ */
+ protected void editAction() {
+ styledTextStringEditor.setBackground(EDIT);
+ edit = true;
+ final Object currentValue = getValue();
+ if (currentValue != null && valueFactory != null && valueFactory.canEdit()) {
+ getOperationExecutor(currentValue).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object newValue = valueFactory.edit(editInstanceButton, currentValue);
+
+ // Per the contract of ReferenceValueFactory::edit(), a null return means the object was edited "in place."
+ // In that case, there is nothing further to do
+ if (newValue != null) {
+ setValue(newValue);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+
+ updateLabel();
+ }
+ }, NLS.bind(Messages.ReferenceDialog_editOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "unset" button is selected Sets the current
+ * reference to null
+ */
+ protected void unsetAction() {
+ setValue(null);
+ }
+
+ /**
+ * Updates the displayed label for the current value
+ */
+ @Override
+ public void updateLabel() {
+ if (binding != null) {
+ binding.updateModelToTarget();
+ } else {
+ if (null != labelProvider) {
+ styledTextStringEditor.setValue(labelProvider.getText(getValue()));
+ }
+ }
+ }
+
+ /**
+ * Sets the Content provider for this editor
+ *
+ * @param provider
+ * The content provider used to retrieve the possible values for
+ * this Reference
+ */
+ @Override
+ public void setContentProvider(final IStaticContentProvider provider) {
+ dialog.setContentProvider(new EncapsulatedContentProvider(provider));
+ if (getValue() != null) {
+ setInitialSelection(Collections.singletonList(getValue()));
+ }
+
+ this.contentProvider = provider;
+ }
+
+ /**
+ * Sets the Label provider for this editor If the label provider is null, a
+ * default one will be used. The same label provider is used for both the
+ * editor's label and the selection dialog.
+ *
+ * @param provider
+ * The label provider
+ */
+ @Override
+ public void setLabelProvider(final ILabelProvider provider) {
+ if (provider == null) {
+ setLabelProvider(new LabelProvider());
+ return;
+ }
+
+ dialog.setLabelProvider(provider);
+ this.labelProvider = provider;
+ if (widgetObservable != null) {
+ ((StyledTextReferenceDialogObservableValue) widgetObservable).setLabelProvider(labelProvider);
+ }
+ updateLabel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLabel(final String label) {
+ super.setLabel(label);
+ dialog.setTitle(label);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ if (modelProperty != null) {
+ return modelProperty.getValue();
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isReadOnly() {
+ return !styledTextStringEditor.isEnabled();
+ }
+
+ /**
+ * Set the initial selection.
+ *
+ * @param initialValues
+ * The list of possible values.
+ */
+ protected void setInitialSelection(final List<?> initialValues) {
+ dialog.setInitialElementSelections(initialValues);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#setModelObservable(org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ @Override
+ public void setModelObservable(final IObservableValue modelProperty) {
+ setWidgetObservable(createWidgetObservable(modelProperty));
+ super.setModelObservable(modelProperty);
+ this.styledTextStringEditor.setModelObservable(modelProperty);
+
+ updateControls();
+ }
+
+ /**
+ * This allow to create the widget observable value.
+ *
+ * @param modelProperty
+ * The current observable value.
+ * @return The created {@link StyledTextReferenceDialogObservableValue}.
+ */
+ protected IObservableValue createWidgetObservable(final IObservableValue modelProperty) {
+ return new StyledTextReferenceDialogObservableValue(this, this.styledTextStringEditor.getText(), modelProperty, SWT.FocusOut, labelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)
+ */
+ @Override
+ public void setToolTipText(final String text) {
+ super.setLabelToolTipText(text);
+ styledTextStringEditor.setToolTipText(text);
+ }
+
+ /**
+ * Set the factory.
+ *
+ * @param factory
+ * The reference value factory.
+ */
+ @Override
+ public void setValueFactory(final ReferenceValueFactory factory) {
+ valueFactory = factory;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ Widget widget = e.widget;
+ if (widget == browseValuesButton) {
+ browseAction();
+ } else if (widget == createInstanceButton) {
+ createAction();
+ } else if (widget == editInstanceButton) {
+ editAction();
+ } else if (widget == unsetButton) {
+ unsetAction();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetDefaultSelected(final SelectionEvent e) {
+ // Nothing
+ }
+
+ /**
+ * Updates the buttons' status
+ */
+ @Override
+ public void updateControls() {
+ // Check if the edit & create buttons should be displayed
+ boolean exclude = valueFactory == null || !valueFactory.canCreateObject();
+ setExclusion(editInstanceButton, exclude);
+ setExclusion(createInstanceButton, exclude);
+
+ setExclusion(browseValuesButton, directCreation);
+
+ browseValuesButton.setEnabled(!readOnly);
+
+ // If they are displayed, check if they should be enabled
+ if (!exclude) {
+ editInstanceButton.setEnabled(valueFactory != null && valueFactory.canEdit() && getValue() != null);
+ createInstanceButton.setEnabled(valueFactory != null && valueFactory.canCreateObject() && !readOnly);
+ }
+
+ // Do not display unset if the value is mandatory
+ setExclusion(unsetButton, mandatory);
+ if (!mandatory) {
+ boolean enabled = !readOnly;
+ enabled = enabled && getValue() != null;
+
+ unsetButton.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#update()
+ */
+ @Override
+ public void update() {
+ super.update();
+ updateControls();
+ }
+
+ /**
+ * Set the direct creation value.
+ *
+ * @param directCreation
+ * Boolean to determinate the direct creation value.
+ */
+ @Override
+ public void setDirectCreation(final boolean directCreation) {
+ this.directCreation = directCreation;
+ updateControls();
+ }
+
+ /**
+ * Set the value.
+ *
+ * @param value
+ * The value object.
+ */
+ public void setValue(final Object value) {
+ this.value = value;
+ try {
+ if (modelProperty != null) {
+ modelProperty.setValue(value);
+ error = false;
+ }
+ } catch (Exception e) {
+ error = true;
+
+ }
+
+ updateControls();
+ updateLabel();
+ commit();
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.StructuredViewer#setInput(Object)
+ * @param input
+ * The current input;
+ */
+ public void setInput(final Object input) {
+ this.dialog.setInput(input);
+ }
+
+ /**
+ * Set the mandatory.
+ *
+ * @param mandatory
+ * The mandatory boolean value.
+ */
+ @Override
+ public void setMandatory(final boolean mandatory) {
+ this.mandatory = mandatory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#updateStatus(org.eclipse.core.runtime.IStatus)
+ */
+ @Override
+ public void updateStatus(final IStatus status) {
+
+ if (error) {
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(Messages.ReferenceDialog_0);
+ controlDecoration.setDescriptionText(Messages.ReferenceDialog_1);
+ controlDecoration.show();
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+
+
+ } else {
+ controlDecoration.hide();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (null != changeColorTask) {
+ changeColorTask.cancel();
+ }
+ if (null != timer) {
+ timer.cancel();
+ }
+ if (null != styledTextStringEditor) {
+ styledTextStringEditor.dispose();
+ }
+ super.dispose();
+ }
+
+ /**
+ * This allow to react of cancel of the current task.
+ */
+ private void cancelCurrentTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#changeColorField()
+ */
+ @Override
+ public void changeColorField() {
+ if (!error & !edit) {
+
+ if (null == timer) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ if (StyledTextReferenceDialog.this.isDisposed()) {
+ return;
+ }
+ StyledTextReferenceDialog.this.getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (StyledTextReferenceDialog.this.isDisposed()) {// Bug 434787 : Shouldn't not execute the timer thread if the widget is disposed
+ return;
+ }
+ styledTextStringEditor.setBackground(DEFAULT);
+ styledTextStringEditor.update();
+ }
+
+
+ });
+ }
+ };
+
+ if (errorBinding) {
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ styledTextStringEditor.setBackground(VALID);
+ styledTextStringEditor.update();
+ break;
+ case IStatus.ERROR:
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+ break;
+
+ }
+ }
+ } else {
+ styledTextStringEditor.setBackground(DEFAULT);
+ styledTextStringEditor.update();
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextStringEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextStringEditor.java
new file mode 100644
index 00000000000..becc57dd823
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextStringEditor.java
@@ -0,0 +1,573 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 446865
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.papyrus.infra.widgets.databinding.StyledTextObservableValue;
+import org.eclipse.papyrus.infra.widgets.selectors.StringSelector;
+import org.eclipse.papyrus.infra.widgets.validator.AbstractValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * A Property Editor representing a single-line or multi-line String value as a
+ * Text. This editor's content is validated when the focus is lost, or, if the
+ * editor is single-line, when the Carriage Return is pressed. For a multi-line
+ * editor, ctrl+enter will also validate the editor's content.
+ *
+ * @see SWT#MULTI
+ *
+ * @author Vincent Lorenzo, adapted code from {@link StringEditor}
+ */
+public class StyledTextStringEditor extends AbstractValueEditor implements KeyListener, ModifyListener {
+
+ /**
+ * The text box for editing this editor's value
+ */
+ protected final StyledText text;
+
+ private int delay = 600;
+
+ private boolean validateOnDelay = false;
+
+ private Timer timer;
+
+ private TimerTask currentValidateTask;
+
+ private TimerTask changeColorTask;
+
+ private final static int DEFAULT_HEIGHT_HINT = 55;
+
+ private final static int DEFAULT_WIDTH_HINT = 100;
+
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ */
+ public StyledTextStringEditor(Composite parent, int style) {
+ this(parent, style, null, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param targetValidator
+ * The validator used for the styled text.
+ */
+ public StyledTextStringEditor(final Composite parent, final int style, final AbstractValidator targetValidator) {
+ this(parent, style, null, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT, targetValidator);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ */
+ public StyledTextStringEditor(Composite parent, int style, String label) {
+ this(parent, style, label, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ * @param targetValidator
+ * The validator used for the styled text.
+ */
+ public StyledTextStringEditor(final Composite parent, final int style, final String label, final AbstractValidator targetValidator) {
+ this(parent, style, label, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT, targetValidator);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param heighHint
+ * Height hint of the text area in multiline mode
+ * @param widthHint
+ * Width hint of the text area in multiline mode
+ */
+ public StyledTextStringEditor(Composite parent, int style, int heighHint, int widthHint) {
+ this(parent, style, null, heighHint, widthHint);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ * @param heighHint
+ * Height hint of the text area in multiline mode
+ * @param widthHint
+ * Width hint of the text area in multiline mode
+ */
+ public StyledTextStringEditor(Composite parent, int style, String label, int heighHint, int widthHint) {
+ this(parent, style, label, heighHint, widthHint, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this editor should be displayed
+ * @param style
+ * The style for this editor's text box
+ * @param label
+ * The label for this editor
+ * @param heighHint
+ * Height hint of the text area in multiline mode
+ * @param widthHint
+ * Width hint of the text area in multiline mode
+ * @param targetValidator
+ * The validator used for the styled text.
+ */
+ public StyledTextStringEditor(final Composite parent, final int style, final String label, final int heighHint, final int widthHint, final AbstractValidator targetValidator) {
+ super(parent, label);
+
+ this.targetValidator = targetValidator;
+
+ GridData data = getDefaultLayoutData();
+ data.grabExcessVerticalSpace = true;
+ data.grabExcessHorizontalSpace = true;
+ data.verticalAlignment = SWT.FILL;
+ data.horizontalAlignment = SWT.FILL;
+ int styledTextStyle = style;
+ if ((style & SWT.MULTI) != 0) {
+ data.minimumHeight = heighHint;
+ data.minimumWidth = widthHint;
+ styledTextStyle = style | SWT.V_SCROLL;
+ }
+
+ text = createStyledText(this, null, styledTextStyle);
+ text.setLayoutData(data);
+
+ if (label != null) {
+ super.label.setLayoutData(getLabelLayoutData());
+
+ }
+ text.addKeyListener(this);
+ text.addModifyListener(this);
+ setCommitOnFocusLost(text);
+ controlDecoration = new ControlDecoration(text, SWT.LEFT | SWT.TOP);
+ controlDecoration.hide();
+
+ // we ignore the indentation
+ // data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+
+ // we remove the margin
+ GridLayout layout = (GridLayout) this.getLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+
+ pack();
+ }
+
+
+ /**
+ * Creates a styled text as a part of the form.
+ *
+ * @param parent
+ * the text parent
+ * @param value
+ * the text initial value
+ * @param style
+ * the text style
+ * @return the styled text widget
+ */
+ public StyledText createStyledText(Composite parent, String value, int style) {
+ StyledText txt = new StyledText(parent, style);
+ txt.setText(value);
+ return txt;
+ }
+
+
+ @Override
+ protected GridData getLabelLayoutData() {
+ GridData result = super.getLabelLayoutData();
+ if (text != null) {
+ if ((text.getStyle() & SWT.MULTI) != 0) {
+ result.verticalAlignment = SWT.BEGINNING;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Ignored
+ */
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // Nothing
+ }
+
+ /**
+ * Validates this editor when one of the following events occur : - CR
+ * released - Keypad CR released - Ctrl + [CR | Keypad CR] released
+ *
+ * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ *
+ * @param e
+ */
+ // TODO : we should prevent the \n from being written when validating the
+ // multi-line field with Ctrl + CR
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // We listen on Carriage Return or Ctrl+ Carriage return, depending on
+ // whether the editor is single- or multi-line
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+ if ((text.getStyle() & SWT.MULTI) == 0) { // Single-line : Enter
+ if (e.stateMask == SWT.NONE) {
+ notifyChange();
+ }
+ } else { // Multi-line : Ctrl+Enter
+ if (e.stateMask == SWT.CTRL) {
+ String str = text.getText();
+ if (str.endsWith(StringSelector.LINE_SEPARATOR)) {
+ int newLength = str.length() - StringSelector.LINE_SEPARATOR.length();
+ text.setText(str.substring(0, newLength));
+ text.setSelection(newLength);
+ }
+ notifyChange();
+ }
+ }
+ }
+
+
+ }
+
+ @Override
+ public void setModelObservable(IObservableValue observable) {
+ setWidgetObservable(new StyledTextObservableValue(text, observable, SWT.FocusOut), true);
+ super.setModelObservable(observable);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return String.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ return text.getText();
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ text.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return !text.isEnabled();
+ }
+
+ protected void notifyChange() {
+
+ text.notifyListeners(SWT.FocusOut, new Event());
+ commit();
+ changeColorField();
+ }
+
+ @Override
+ public void setToolTipText(String tooltip) {
+ text.setToolTipText(tooltip);
+ super.setLabelToolTipText(tooltip);
+ }
+
+ /**
+ * Sets the current text value for this editor
+ *
+ * @param value
+ */
+ public void setValue(Object value) {
+ if (value instanceof String) {
+ this.text.setText((String) value);
+ } else {
+ this.text.setText(""); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Indicates that this editor should be automatically validated after a
+ * timer.
+ *
+ * @param validateOnDelay
+ */
+ public void setValidateOnDelay(boolean validateOnDelay) {
+ this.validateOnDelay = validateOnDelay;
+
+ if (validateOnDelay) {
+ text.addModifyListener(this);
+ } else {
+ text.removeModifyListener(this);
+ cancelCurrentTask();
+ }
+ }
+
+ /**
+ * Indicates that this editor should be automatically validated after the
+ * given timer
+ *
+ * @param millis
+ * The delay after which the editor should be automatically
+ * validated, in milliseconds. The default is 600ms
+ */
+ public void setValidateOnDelay(int millis) {
+ this.delay = millis;
+ setValidateOnDelay(true);
+ if (delay == 0) {
+ cancelCurrentTask();
+ }
+ }
+
+ private void cancelCurrentTask() {
+ if (currentValidateTask != null) {
+ currentValidateTask.cancel();
+ currentValidateTask = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ // SWT Thread
+ if (validateOnDelay) {
+ if (delay == 0) {
+ commit(); // Direct commit on edition, to avoid creating useless
+ // threads
+
+ return;
+ }
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ currentValidateTask = new TimerTask() {
+
+ // Timer thread
+ @Override
+ public void run() {
+ StyledTextStringEditor.this.getDisplay().syncExec(new Runnable() {
+
+ // SWT Thread
+ @Override
+ public void run() {
+
+ commit();
+ }
+ });
+ }
+ };
+ timer.schedule(currentValidateTask, delay);
+ }
+ if (targetValidator != null) {
+ IStatus status = targetValidator.validate(getTextToValidate());
+ updateStatus(status);
+ }
+ if (modelValidator != null) {
+ IStatus status = modelValidator.validate(getTextToValidate());
+ updateStatus(status);
+ if (binding == null) {
+ update();
+ }
+ }
+
+ if (modelProperty != null) { // Bug 433169: The widget may be used without an Observable Value (setValue + getValue)
+ if (modelProperty.getValue() != null) {
+ if (!isReadOnly() && !modelProperty.getValue().toString().equals(text.getText())) {
+ text.setBackground(EDIT);
+ } else {
+ text.setBackground(DEFAULT);
+ }
+ } else {
+ if (text.getText().equals("")) {
+ text.setBackground(DEFAULT);
+ } else {
+ text.setBackground(EDIT);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the string to validate.
+ *
+ * @return The string text to validate.
+ */
+ protected String getTextToValidate() {
+ return text.getText();
+ }
+
+ @Override
+ public void dispose() {
+ cancelCurrentTask();
+ cancelChangeColorTask();
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ super.dispose();
+ }
+
+ public StyledText getText() {
+ return text;
+ }
+
+ @Override
+ public void updateStatus(IStatus status) {
+ if(!isDisposed()){
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ controlDecoration.hide();
+ break;
+ case IStatus.WARNING:
+ FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+ controlDecoration.setImage(warning.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ case IStatus.ERROR:
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(status.getMessage());
+ controlDecoration.setDescriptionText(status.getMessage());
+ controlDecoration.show();
+ break;
+ default:
+ controlDecoration.hide();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void changeColorField() {
+ if (binding != null) {
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelChangeColorTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ if (StyledTextStringEditor.this.isDisposed()) {
+ return;
+ }
+ StyledTextStringEditor.this.getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if(!text.isDisposed()){
+ text.setBackground(DEFAULT);
+ text.update();
+ }
+ }
+ });
+ }
+ };
+ if (errorBinding) {
+ if(!text.isDisposed()){
+ text.setBackground(ERROR);
+ text.update();
+ }
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ if(!text.isDisposed()){
+ text.setBackground(VALID);
+ text.update();
+ }
+ break;
+ case IStatus.ERROR:
+ if(!text.isDisposed()){
+ text.setBackground(ERROR);
+ text.update();
+ }
+ break;
+
+ }
+ }
+ }
+ }
+
+ private void cancelChangeColorTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ changeColorTask = null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TreeSelectorDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TreeSelectorDialog.java
new file mode 100644
index 00000000000..6d09eb33775
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TreeSelectorDialog.java
@@ -0,0 +1,270 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 408491
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IGraphicalContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider;
+import org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * A Dialog for selecting values. The values are displayed as a Tree. If only
+ * some of the values of this Tree should be selectable, you should pass a {@link IHierarchicContentProvider} to this dialog.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class TreeSelectorDialog extends SelectionDialog implements ITreeSelectorDialog {
+
+ private ILabelProvider labelProvider;
+
+ private ITreeContentProvider contentProvider;
+
+ private TreeViewer treeViewer;
+
+ private String description;
+
+ private Label descriptionLabel;
+
+ private Object input = null;
+
+ private final Set<ICommitListener> commitListeners = new HashSet<ICommitListener>();
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * The parent shell in which this dialog will be opened
+ */
+ public TreeSelectorDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ /**
+ * Sets the label provider for this dialog
+ *
+ * @param provider
+ */
+ @Override
+ public void setLabelProvider(ILabelProvider provider) {
+ labelProvider = provider;
+ if (treeViewer != null) {
+ treeViewer.setLabelProvider(labelProvider);
+ }
+ }
+
+ /**
+ * Sets the ContentProvider for this dialog
+ * The ContentProvider may be a {@link IHierarchicContentProvider}
+ *
+ * @param provider
+ * The content provider for this dialog. May be a {@link IHierarchicContentProvider}
+ */
+ @Override
+ public void setContentProvider(ITreeContentProvider provider) {
+ contentProvider = provider;
+ if (treeViewer != null) {
+ initViewerAndProvider();
+ }
+ if (contentProvider instanceof ICommitListener) {
+ commitListeners.add((ICommitListener) contentProvider);
+ }
+ }
+
+ protected void initViewerAndProvider() {
+ treeViewer.setContentProvider(contentProvider);
+ if (treeViewer.getInput() == null) {
+ doSetInput();
+ }
+ }
+
+ @Override
+ protected Composite getDialogArea() {
+ return (Composite) super.getDialogArea();
+ }
+
+ @Override
+ public void create() {
+ super.create();
+
+ descriptionLabel = new Label(getDialogArea(), SWT.WRAP);
+ descriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ if (description != null) {
+ descriptionLabel.setText(description);
+ }
+
+ treeViewer = new TreeViewer(getDialogArea(), SWT.BORDER);
+ // treeViewer.setFilters(new ViewerFilter[]{ new PatternFilter() });
+
+ if (labelProvider != null) {
+ treeViewer.setLabelProvider(labelProvider);
+ }
+ if (contentProvider != null) {
+ initViewerAndProvider();
+ }
+
+ treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+
+ Object selectedElement = null;
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ IStructuredSelection sSelection = (IStructuredSelection) selection;
+ selectedElement = sSelection.getFirstElement();
+ }
+
+ if (contentProvider instanceof IHierarchicContentProvider) {
+ boolean isValidValue = ((IHierarchicContentProvider) contentProvider).isValidValue(selectedElement);
+ if (contentProvider instanceof IAdaptableContentProvider) {
+ selectedElement = ((IAdaptableContentProvider) contentProvider).getAdaptedValue(selectedElement);
+ }
+ if (isValidValue) {
+ setResult(Collections.singletonList(selectedElement));
+ } else {
+ setResult(Collections.EMPTY_LIST);
+ }
+ getOkButton().setEnabled(isValidValue);
+ }
+ }
+ });
+
+ treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ if (getOkButton().isEnabled()) {
+ okPressed();
+ }
+ }
+
+ });
+
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.minimumHeight = 300;
+ data.minimumWidth = 300;
+ treeViewer.getTree().setLayoutData(data);
+
+ if (contentProvider instanceof IGraphicalContentProvider) {
+ IGraphicalContentProvider graphicalContentProvider = (IGraphicalContentProvider) contentProvider;
+
+ Composite beforeTreeComposite = new Composite(getDialogArea(), SWT.NONE);
+ beforeTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ beforeTreeComposite.setLayout(new FillLayout());
+ graphicalContentProvider.createBefore(beforeTreeComposite);
+
+ beforeTreeComposite.moveAbove(treeViewer.getTree());
+
+ Composite afterTreeComposite = new Composite(getDialogArea(), SWT.NONE);
+ afterTreeComposite.setLayout(new FillLayout());
+ afterTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ graphicalContentProvider.createAfter(afterTreeComposite);
+ }
+
+ List<?> initialSelection = getInitialElementSelections();
+ if (contentProvider instanceof IRevealSemanticElement) {
+ ((IRevealSemanticElement) contentProvider).revealSemanticElement(initialSelection);
+ } else if (!initialSelection.isEmpty()) {
+ // FIXME : When we use an EncapsulatedContentProvider, we'll not get into this case,
+ // even if the encapsulated provider is not a IRevealSemanticElement
+ treeViewer.setSelection(new StructuredSelection(initialSelection.get(0)), true);
+ }
+
+ getShell().setDefaultButton(null);
+ getButton(OK).setFocus();
+ getShell().setImage(Activator.getDefault().getImage("/icons/papyrus.png")); //$NON-NLS-1$
+ getShell().pack();
+
+ }
+
+ /**
+ * Sets the description for this Dialog. The description is displayed on
+ * top of the dialog
+ *
+ * @param description
+ * The description for this dialog
+ */
+ @Override
+ public void setDescription(String description) {
+ this.description = description;
+
+ if ((descriptionLabel != null) && !descriptionLabel.isDisposed()) {
+ descriptionLabel.setText(description == null ? "" : description); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Get the TreeViewer used by this dialog
+ *
+ * @return
+ * The TreeViewer associated to this dialog
+ */
+ protected TreeViewer getViewer() {
+ return treeViewer;
+ }
+
+ /**
+ * Sets the input object for this dialog's TreeViewer
+ *
+ * @param input
+ */
+ @Override
+ public void setInput(Object input) {
+ this.input = input;
+ }
+
+ private void doSetInput() {
+ if (input == null) {
+ // Default non-null input for IStaticContentProvider (input-independent)
+ treeViewer.setInput(""); //$NON-NLS-1$
+ } else {
+ treeViewer.setInput(input);
+ }
+ }
+
+ @Override
+ public void okPressed() {
+ for (ICommitListener listener : commitListeners) {
+ listener.commit(null);
+ }
+ super.okPressed();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TwoInputDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TwoInputDialog.java
new file mode 100644
index 00000000000..cab1ce17e24
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/TwoInputDialog.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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+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;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * This Dialog provides 2 texts field. It was created to be used during the table creation.
+ * It doesn't provide validator for the second field.
+ *
+ *
+ */
+public class TwoInputDialog extends InputDialog {
+
+ /** widget for the second value */
+ private Text text_2;
+
+ /** the second values */
+ private String value_2;
+
+ /** the message for the second Text */
+ protected String message_2;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parentShell
+ * the parent shell
+ * @param dialogTitle
+ * the dialog title
+ * @param message1
+ * the first message for the dialog
+ * @param message2
+ * the second message for the dialog
+ * @param initialValue1
+ * the first initial value
+ * @param initialValue2
+ * the second initial value
+ * @param validator
+ * the validator
+ */
+ public TwoInputDialog(Shell parentShell, String dialogTitle, String message1, String message2, String initialValue1, String initialValue2, IInputValidator validator) {
+ super(parentShell, dialogTitle, message1, initialValue1, validator);
+ this.message_2 = message2;
+ this.value_2 = initialValue2;
+ }
+
+ /**
+ * Create the second Text Area
+ *
+ * @see org.eclipse.jface.dialogs.InputDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ *
+ * @param parent
+ * @return
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ if (message_2 != null) {
+ Label label = new Label(composite, SWT.WRAP);
+ label.setText(message_2);
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
+ data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+ label.setLayoutData(data);
+ label.setFont(parent.getFont());
+ }
+ text_2 = new Text(composite, getInputTextStyle());
+ text_2.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
+ applyDialogFont(composite);
+ return composite;
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.dialogs.InputDialog#buttonPressed(int)
+ *
+ * @param buttonId
+ */
+ @Override
+ protected void buttonPressed(int buttonId) {
+ if (buttonId == IDialogConstants.OK_ID) {
+ this.value_2 = this.text_2.getText();
+ } else {
+ this.value_2 = null;
+ }
+ super.buttonPressed(buttonId);
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.dialogs.InputDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+ *
+ * @param parent
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ if (value_2 != null) {
+ text_2.setText(value_2);
+ }
+ }
+
+ /**
+ * Getter for {@link #value_2}
+ *
+ * @return
+ * the description for the table
+ */
+ public String getValue_2() {
+ return this.value_2;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/UnlimitedNaturalEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/UnlimitedNaturalEditor.java
new file mode 100644
index 00000000000..35aa1aa7b42
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/UnlimitedNaturalEditor.java
@@ -0,0 +1,125 @@
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.conversion.StringToNumberConverter;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.validator.UnlimitedNaturalValidator;
+import org.eclipse.swt.widgets.Composite;
+
+public class UnlimitedNaturalEditor extends StringEditor {
+ /**
+ * The IConverter for converting data from the widget to the model
+ */
+ private IConverter targetToModelConverter;
+
+ /**
+ * Constructs an editor for Integer values. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The Text's style
+ */
+ public UnlimitedNaturalEditor(Composite parent, int style) {
+ this(parent, style, null);
+ }
+
+ /**
+ * Constructs an editor for Integer values. The widget is a Text field.
+ *
+ * @param parent
+ * The Composite in which this editor is created
+ * @param style
+ * The Text's style
+ * @param label
+ * The editor's label
+ */
+ public UnlimitedNaturalEditor(Composite parent, int style, String label) {
+ super(parent, style, label);
+
+ targetValidator = new UnlimitedNaturalValidator();
+
+ targetToModelConverter = new IConverter() {
+
+ @Override
+ public Object getToType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Object getFromType() {
+ return String.class;
+ }
+
+ @Override
+ public Integer convert(Object fromObject) {
+ if (fromObject instanceof String) {
+ String newString = ((String) fromObject).replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ if (newString.equals("*"))
+ {
+ return -1;
+ }
+ return (Integer) StringToNumberConverter.toInteger(false).convert(newString);
+ }
+ return 0;
+ }
+ };
+
+ IConverter integerToString = new IConverter() {
+
+ @Override
+ public Object getToType() {
+ return String.class;
+ }
+
+ @Override
+ public Object getFromType() {
+ return Integer.class;
+ }
+
+ @Override
+ public Object convert(Object fromObject) {
+ if (fromObject instanceof Integer) {
+ if (((Integer) fromObject).intValue() == -1) {
+ return "*"; //$NON-NLS-1$
+ }
+ return Integer.toString((Integer) fromObject);
+ }
+ return ""; //$NON-NLS-1$
+ }
+ };
+ setValidateOnDelay(true);
+
+ setConverters(targetToModelConverter, integerToString);
+ setTargetAfterGetValidator(targetValidator);
+
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Integer.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer getValue() {
+ try {
+
+ return (Integer) targetToModelConverter.convert(super.getValue());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+ }
+
+
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java
new file mode 100644
index 00000000000..9cc4b1d79c0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.messages;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * The Class Messages.
+ */
+public class Messages extends NLS {
+
+ /** The Constant BUNDLE_NAME. */
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.widgets.messages.messages"; //$NON-NLS-1$
+
+ public static String BooleanInputValidator_NotABoolean;
+
+ public static String IntegerInputValidator_NotAnIntegerMessage;
+
+ public static String RealInputValidator_NotaRealMessage;
+
+ public static String UnlimitedNaturalInputValidator_NotAnUnlimitedNaturalMessage;
+
+ public static String MultipleStringFileEditor_0;
+
+ public static String MultipleStringFileEditor_1;
+
+ public static String MultipleStringFileEditor_2;
+
+ public static String MultipleValueEditAndSelectionWidget_EditSelectedElement;
+
+ /** The Multiple value editor_ add elements. */
+ public static String MultipleValueEditor_AddElements;
+
+ public static String MultipleValueEditor_addOperation;
+
+ public static String MultipleValueEditor_editOperation;
+
+ /** The Multiple value editor_ edit selected value */
+ public static String MultipleValueEditor_EditSelectedValue;
+
+ /** The Multiple value editor_ move selected elements down. */
+ public static String MultipleValueEditor_MoveSelectedElementsDown;
+
+ /** The Multiple value editor_ move selected elements up. */
+ public static String MultipleValueEditor_MoveSelectedElementsUp;
+
+ /** The Multiple value editor_ remove selected elements. */
+ public static String MultipleValueEditor_RemoveSelectedElements;
+
+ /** The Multiple value selector dialog_ add all elements. */
+ public static String MultipleValueSelectorDialog_AddAllElements;
+
+ /** The Multiple value selector dialog_ add selected elements. */
+ public static String MultipleValueSelectorDialog_AddSelectedElements;
+
+ /** The Multiple value selector dialog_ create new element */
+ public static String MultipleValueSelectorDialog_CreateNewElement;
+
+ /** The Multiple value selector dialog_ delete new element */
+ public static String MultipleValueSelectorDialog_DeleteNewElement;
+
+ /** The Multiple value selector dialog_ remove all elements. */
+ public static String MultipleValueSelectorDialog_RemoveAllElements;
+
+ public static String ReferenceDialog_0;
+
+ public static String ReferenceDialog_1;
+
+ public static String ReferenceDialog_CreateANewObject;
+
+ public static String ReferenceDialog_editOperation;
+
+ public static String ReferenceDialog_EditTheCurrentValue;
+
+ /** The Reference dialog_ edit value */
+ public static String ReferenceDialog_EditValue;
+
+ /** The Reference dialog_ select value */
+ public static String ReferenceDialog_SelectValue;
+
+ public static String ReferenceDialog_setOperation;
+
+ /** The Reference dialog_ unset */
+ public static String ReferenceDialog_Unset;
+
+ /** The Reference dialog_ edit unset value */
+ public static String ReferenceDialog_UnsetValue;
+
+ /** Indicates that a list of elements have different values for the given property (Multi-selection) */
+ public static String ReferenceDialogObservable_Unchanged;
+
+ /** The switch editors label for Multiplicity reference dialog. */
+ public static String MultiplicityReferenceDialog_SwitchEditors;
+
+ /** The lower value tool tip for Multiplicity reference dialog. */
+ public static String MultiplicityReferenceDialog_LowerValueToolTip;
+
+ /** The upper value tool tip for Multiplicity reference dialog. */
+ public static String MultiplicityReferenceDialog_UpperValueToolTip;
+
+ /** the Enum radio_ no value */
+ public static String EnumRadio_NoValue;
+
+ public static String FlattenableRestrictedFilteredContentProvider_AllPossibleContentsMessage;
+
+ public static String FlattenableRestrictedFilteredContentProvider_FlatViewMessage;
+
+ public static String IntegerMask_ErrorTooManyValues;
+
+ public static String ProviderBasedBrowseStrategy_0;
+
+ public static String StringEditionFactory_EnterANewValue;
+
+ public static String StringFileSelector_0;
+
+ public static String StringFileSelector_Browse;
+
+ public static String StringFileSelector_BrowseWorkspace;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Instantiates a new messages.
+ */
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties
new file mode 100644
index 00000000000..2aa21d64ea1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties
@@ -0,0 +1,57 @@
+###############################################################################
+# Copyright (c) 2010, 2014 CEA LIST 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:
+# Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+# Christian W. Damus (CEA) - bug 402525
+#
+###############################################################################
+
+BooleanInputValidator_NotABoolean=The actual entry is not a Boolean.
+IntegerInputValidator_NotAnIntegerMessage=The actual entry is not an Integer.
+RealInputValidator_NotaRealMessage=The actual entry is not a Real.
+UnlimitedNaturalInputValidator_NotAnUnlimitedNaturalMessage=The actual entry is not an UnlimitedNatural. An UnlimitedNatural must be either -1, * or >= 0
+MultipleStringFileEditor_0=Browse file system
+MultipleStringFileEditor_1=Browse workspace
+MultipleStringFileEditor_2=FilterExtensions and FilterNames do not match
+MultipleValueEditAndSelectionWidget_EditSelectedElement=Edit selected Element
+MultipleValueEditor_AddElements=Add elements
+MultipleValueEditor_addOperation=Add {0}
+MultipleValueEditor_editOperation=Edit {0}
+MultipleValueEditor_EditSelectedValue=Edit the selected value
+MultipleValueEditor_MoveSelectedElementsDown=Move selected elements down
+MultipleValueEditor_MoveSelectedElementsUp=Move selected elements up
+MultipleValueEditor_RemoveSelectedElements=Remove selected elements
+MultipleValueSelectorDialog_AddAllElements=Add all elements
+MultipleValueSelectorDialog_AddSelectedElements=Add selected elements
+MultipleValueSelectorDialog_RemoveAllElements=Remove all elements
+MultipleValueSelectorDialog_CreateNewElement=Create a new element
+MultipleValueSelectorDialog_DeleteNewElement=Deletes a newly created element
+ReferenceDialog_0=An error occured while setting the value.
+ReferenceDialog_1=An error occured while setting the value.
+ReferenceDialog_CreateANewObject=Create a new object
+ReferenceDialog_editOperation=Edit {0}
+ReferenceDialog_EditTheCurrentValue=Edit the current value
+ReferenceDialog_EditValue=Edit the reference value
+ReferenceDialog_SelectValue=Select the value for this reference
+ReferenceDialog_setOperation=Set {0}
+ReferenceDialog_Unset=<Undefined>
+ReferenceDialog_UnsetValue=Unset the reference value
+ReferenceDialogObservable_Unchanged=<Unchanged>
+MultiplicityReferenceDialog_SwitchEditors=Switch editors
+MultiplicityReferenceDialog_LowerValueToolTip=Lower ValueSpecification
+MultiplicityReferenceDialog_UpperValueToolTip=Upper ValueSpecification
+EnumRadio_NoValue=There is no value to select
+FlattenableRestrictedFilteredContentProvider_AllPossibleContentsMessage=Show all possible values
+FlattenableRestrictedFilteredContentProvider_FlatViewMessage=Flat View
+StringEditionFactory_EnterANewValue=Enter the new value
+StringFileSelector_0=FilterExtensions and FilterNames do not match
+StringFileSelector_Browse=Browse
+StringFileSelector_BrowseWorkspace=Browse workspace
+IntegerMask_ErrorTooManyValues=The mask-based integer editor cannot be used with more than 32 values
+ProviderBasedBrowseStrategy_0=The provider has not been initialized
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractFilteredContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractFilteredContentProvider.java
new file mode 100644
index 00000000000..7b3ca25ce68
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractFilteredContentProvider.java
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.editors.StringEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * A generic implementation for a IGraphicalContentProvider.
+ * This class doesn't provide any element, and should be extended.
+ *
+ * It implements a filter for List or Tree elements, based on the label
+ * provided by the viewer's label provider (Or Object#toString() if the viewer
+ * doesn't have a label provider).
+ *
+ * A Text widget is added before the display control to insert the filter
+ * pattern. An element is matched if at least one of these conditions is
+ * matched :
+ * - The element's name matches the pattern
+ * - One of the element's children matches the pattern
+ * - One of the element's parent matches the pattern
+ *
+ * The elements' hierarchy is obtained via the viewer's ContentProvider.
+ *
+ * @author Camille Letavernier
+ */
+// TODO : Encapsulate a IStructuredContentProvider and make this class concrete
+public abstract class AbstractFilteredContentProvider implements IGraphicalContentProvider {
+
+ protected StructuredViewer viewer;
+
+ private StringEditor filterPattern;
+
+ private PatternViewerFilter filter;
+
+ public static final String BASE_PATTERN = "*"; //$NON-NLS-1$
+
+ protected boolean showIfHasVisibleParent = false;
+
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (viewer instanceof StructuredViewer) {
+ this.viewer = (StructuredViewer) viewer;
+ updateFilter();
+ }
+ }
+
+ private void updateFilter() {
+ if (this.viewer != null && filterPattern != null) {
+ this.viewer.setFilters(new ViewerFilter[] { filter });
+ }
+ }
+
+ @Override
+ public void createBefore(Composite parent) {
+ filterPattern = new StringEditor(parent, SWT.NONE, "Filter : "); //$NON-NLS-1$
+ filterPattern.setValidateOnDelay(true);
+ filterPattern.setValue(BASE_PATTERN);
+ filter = getViewerFilter();
+ filterPattern.addCommitListener(new ICommitListener() {
+
+ @Override
+ public void commit(AbstractEditor editor) {
+ filter.setPattern((String) filterPattern.getValue());
+ viewer.refresh();
+ }
+
+ });
+ updateFilter();
+ }
+
+ @Override
+ public void createAfter(Composite parent) {
+ // Nothing
+ }
+
+ protected PatternViewerFilter getViewerFilter() {
+ PatternViewerFilter filter = new PatternViewerFilter();
+ filter.setStrict(false);
+ filter.setPattern(BASE_PATTERN);
+ filter.setShowIfHasVisibleParent(showIfHasVisibleParent);
+ return filter;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractRestrictedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractRestrictedContentProvider.java
new file mode 100644
index 00000000000..975d647d439
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractRestrictedContentProvider.java
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Juan Cadavid (CEA LIST) juan.cadavid@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Abstract Implementation for {@link IRestrictedContentProvider}
+ *
+ * @author JC236769
+ *
+ */
+public abstract class AbstractRestrictedContentProvider implements IRestrictedContentProvider {
+
+ /**
+ * flag to indicate the useage of the restriction in the content provider
+ */
+ private boolean isRestricted;
+
+ /**
+ * if <code>false</code> the inherited features will be displayed
+ */
+ private boolean ignoreInheritedFeatures;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param isRestricted
+ */
+ public AbstractRestrictedContentProvider(final boolean isRestricted) {
+ this.isRestricted = isRestricted;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IRestrictedContentProvider#setRestriction(boolean)
+ *
+ * @param isRestricted
+ */
+ @Override
+ public final void setRestriction(boolean isRestricted) {
+ this.isRestricted = isRestricted;
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ *
+ * @param viewer
+ * @param oldInput
+ * @param newInput
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#setIgnoreInheritedElements(boolean)
+ *
+ * @param ignoreInheritedElements
+ */
+ @Override
+ public void setIgnoreInheritedElements(boolean ignoreInheritedElements) {
+ this.ignoreInheritedFeatures = ignoreInheritedElements;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#isIgnoringInheritedElements()
+ *
+ * @return
+ */
+ @Override
+ public boolean isIgnoringInheritedElements() {
+ return this.ignoreInheritedFeatures;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IRestrictedContentProvider#isRestricted()
+ *
+ * @return
+ */
+ @Override
+ public boolean isRestricted() {
+ return this.isRestricted;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractStaticContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractStaticContentProvider.java
new file mode 100644
index 00000000000..3f41f74abc8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractStaticContentProvider.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * An empty implementation of IStaticContentProvider
+ *
+ * @author Camille Letavernier
+ *
+ */
+public abstract class AbstractStaticContentProvider implements IStaticContentProvider {
+
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Nothing
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getElements();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java
new file mode 100644
index 00000000000..6d1a42c2492
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.infra.widgets.strategy.IStrategyBasedContentProvider;
+import org.eclipse.papyrus.infra.widgets.strategy.ProviderBasedBrowseStrategy;
+import org.eclipse.papyrus.infra.widgets.strategy.TreeBrowseStrategy;
+
+/**
+ * An abstract ViewerFilter for TreeViewers.
+ *
+ * You should extend this class whenever you want to implement a filter
+ * for a Tree. An element is visible :
+ * - If the method isVisible() returns true
+ * - If one of its children is visible
+ * - Optionally, if one of its parents is visible ({@link #showIfHasVisibleParent})
+ *
+ * This class can implements a cache, which should be cleaned each time
+ * a parameter influencing the result of the {@link #isVisible(Viewer, Object, Object)} method is changed ({@link #clearCache()}).
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractTreeFilter extends ViewerFilter {
+
+ /**
+ * If set to true, the results of the filter will be cached, to improve
+ * performance.
+ *
+ * Implementers are responsible of cleaning the cache (by calling {@link #clearCache()} when the result of the filter on a given
+ * element might change.
+ *
+ * For example, a string-pattern-based filter should clear the cache when
+ * the pattern changes. The viewer should also be refreshed.
+ */
+ protected boolean useCache = true;
+
+ /**
+ * Indicates if an element should be visible when one its parents is visible.
+ * This may be useful, for example, when you want to display all the contents
+ * of a given package, by entering a filter that will match this package.
+ */
+ protected boolean showIfHasVisibleParent = false;
+
+ /**
+ * Cache
+ */
+ protected final Map<Object, Boolean> visibleElement = new HashMap<Object, Boolean>();
+
+ /**
+ * Cache
+ */
+ protected final Map<Object, Boolean> visibleParent = new HashMap<Object, Boolean>();
+
+ /**
+ * Cache
+ */
+ protected final Map<Object, Boolean> visibleChild = new HashMap<Object, Boolean>();
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+
+ TreeBrowseStrategy strategy = null;
+
+ if (viewer instanceof StructuredViewer) {
+ IContentProvider baseContentProvider = ((StructuredViewer) viewer).getContentProvider();
+ if (baseContentProvider instanceof IStrategyBasedContentProvider) {
+ strategy = ((IStrategyBasedContentProvider) baseContentProvider).getRevealStrategy();
+ }
+
+ if (strategy == null && baseContentProvider instanceof ITreeContentProvider) {
+ strategy = new ProviderBasedBrowseStrategy((ITreeContentProvider) baseContentProvider);
+ }
+ }
+
+ if (strategy == null) { // The contentProvider is not a TreeContentProvider
+ return isVisible(viewer, parentElement, element);
+ }
+
+ return select(viewer, parentElement, element, strategy);
+ }
+
+ protected boolean select(Viewer viewer, Object parentElement, Object element, TreeBrowseStrategy strategy) {
+ Set<Object> visitedChildren = new HashSet<Object>();
+ Set<Object> visitedParents = new HashSet<Object>();
+ if (useCache && visibleElement.containsKey(element)) {
+ return visibleElement.get(element);
+ }
+
+ boolean isVisible = isVisible(viewer, parentElement, element) || hasOneVisibleChild(viewer, element, strategy, visitedChildren);
+
+ if (showIfHasVisibleParent) {
+ isVisible = isVisible || hasOneVisibleParent(viewer, element, strategy, visitedParents);
+ }
+
+ if (useCache) {
+ visibleElement.put(element, isVisible);
+ }
+
+ return isVisible;
+ }
+
+ protected boolean hasOneVisibleChild(Viewer viewer, Object element, TreeBrowseStrategy strategy, Set<Object> visitedElements) {
+ // TODO : separate this method in -hasOneVisibleChild() and #doHasOneVisibleChild(), to handle the cache management in a private method,
+ // while letting the opportunity to override the method
+ if (useCache && visibleChild.containsKey(element)) {
+ return visibleChild.get(element);
+ }
+
+ boolean result = false;
+ if (!visitedElements.contains(element)) {
+ visitedElements.add(element);
+
+ for (Object childElement : strategy.getChildren(element)) {
+ if (isVisible(viewer, element, childElement) || hasOneVisibleChild(viewer, childElement, strategy, visitedElements)) {
+ result = true;
+ break;
+ }
+ }
+ }
+
+ if (useCache) {
+ visibleChild.put(element, result);
+ }
+ return result;
+ }
+
+ protected boolean hasOneVisibleParent(Viewer viewer, Object element, TreeBrowseStrategy strategy, Set<Object> visitedElements) {
+ if (useCache && visibleParent.containsKey(element)) {
+ return visibleParent.get(element);
+ }
+
+ boolean result = false;
+ if (!visitedElements.contains(element)) {
+
+ visitedElements.add(element);
+
+ Object parentElement = strategy.getParent(element);
+ if (parentElement == element || parentElement == null) {
+ result = isVisible(viewer, parentElement, element);
+ } else {
+ result = isVisible(viewer, null, parentElement) || hasOneVisibleParent(viewer, parentElement, strategy, visitedElements);
+ }
+ }
+
+ if (useCache) {
+ visibleParent.put(element, result);
+ }
+
+ return result;
+ }
+
+ protected void clearCache() {
+ visibleElement.clear();
+ visibleParent.clear();
+ visibleChild.clear();
+ }
+
+ public abstract boolean isVisible(Viewer viewer, Object parentElement, Object element);
+
+ public void setShowIfHasVisibleParent(boolean showIfHasVisibleParent) {
+ this.showIfHasVisibleParent = showIfHasVisibleParent;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CollectionContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CollectionContentProvider.java
new file mode 100644
index 00000000000..44f3743b265
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CollectionContentProvider.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import java.util.Collection;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * A Content Provider converting the input list to an array containing the same elements
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class CollectionContentProvider implements ITreeContentProvider {
+
+ private CollectionContentProvider() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Nothing
+ }
+
+ /**
+ * Converts the input List to an Array containing the same elements
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ *
+ * @param inputElement
+ * @return
+ * The Array containing the input elements
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof Collection) {
+ return ((Collection<?>) inputElement).toArray();
+ } else if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ }
+
+ return new Object[] {};
+ }
+
+ /**
+ * The Singleton instance
+ */
+ public static final CollectionContentProvider instance = new CollectionContentProvider();
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return new Object[0]; // Flat tree
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return null; // Flat tree
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ComboLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ComboLabelProvider.java
new file mode 100644
index 00000000000..67b65053a55
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ComboLabelProvider.java
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+
+public class ComboLabelProvider extends LabelProvider {
+
+ private ILabelProvider labelProvider;
+
+ public ComboLabelProvider(IBaseLabelProvider encapsulated) {
+ this.labelProvider = (ILabelProvider) encapsulated;
+ }
+
+ @Override
+ public String getText(Object value) {
+ if (value == UnsetObject.instance || value == UnchangedObject.instance) {
+ return value.toString();
+ }
+ return labelProvider.getText(value);
+ }
+
+ @Override
+ public Image getImage(Object value) {
+ if (value == UnsetObject.instance || value == UnchangedObject.instance) {
+ return null;
+ }
+ return labelProvider.getImage(value);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompositeContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompositeContentProvider.java
new file mode 100644
index 00000000000..91bd6ae32ce
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompositeContentProvider.java
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+public class CompositeContentProvider implements ICompositeContentProvider {
+
+ private final List<ITreeContentProvider> contentProviders;
+
+ public CompositeContentProvider() {
+ contentProviders = new LinkedList<ITreeContentProvider>();
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ List<Object> result = new LinkedList<Object>();
+ for (ITreeContentProvider provider : contentProviders) {
+ result.addAll(Arrays.asList(provider.getElements(inputElement)));
+ }
+ return result.toArray();
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ List<Object> result = new LinkedList<Object>();
+ for (ITreeContentProvider provider : contentProviders) {
+ result.addAll(Arrays.asList(provider.getChildren(parentElement)));
+ }
+ return result.toArray();
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ for (ITreeContentProvider provider : contentProviders) {
+ Object parent = provider.getParent(element);
+ if (parent != null) {
+ return parent;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ @Override
+ public void dispose() {
+ for (ITreeContentProvider provider : contentProviders) {
+ provider.dispose();
+ }
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ for (ITreeContentProvider provider : contentProviders) {
+ provider.inputChanged(viewer, oldInput, newInput);
+ }
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ for (ITreeContentProvider provider : contentProviders) {
+ if (provider instanceof IHierarchicContentProvider) {
+ if (((IHierarchicContentProvider) provider).isValidValue(element)) {
+ return true;
+ }
+ } else {
+ return true; // For non-hierarchic content providers, isValidValue is always true
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void appendContentProvider(ITreeContentProvider treeContentProvider) {
+ contentProviders.add(treeContentProvider);
+ }
+
+ public List<ITreeContentProvider> getContentProviders() {
+ return contentProviders;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompoundFilteredRestrictedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompoundFilteredRestrictedContentProvider.java
new file mode 100644
index 00000000000..9a72314334f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/CompoundFilteredRestrictedContentProvider.java
@@ -0,0 +1,149 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Juan Cadavid (CEA LIST) juan.cadavid@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * This class allows to use several content provider for the same widget
+ * + restriction behavior see {@link IRestrictedContentProvider} documentation
+ *
+ * @author JC236769
+ *
+ */
+public class CompoundFilteredRestrictedContentProvider extends AbstractFilteredContentProvider implements IRestrictedContentProvider {
+
+ private List<IRestrictedContentProvider> encapsulatedContentProviders = new ArrayList<IRestrictedContentProvider>();
+
+ public boolean add(IRestrictedContentProvider o) {
+ if (o != null) {
+ return encapsulatedContentProviders.add(o);
+ }
+ return false;
+ }
+
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ Collection<Object> asList = new HashSet<Object>();
+
+ for (IRestrictedContentProvider encapsulatedContentProvider : encapsulatedContentProviders) {
+ Object[] directElements = encapsulatedContentProvider.getElements(inputElement);
+ asList.addAll(Arrays.asList(directElements));
+ }
+ return asList.toArray();
+ }
+
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ Collection<Object> asList = new HashSet<Object>();
+
+ for (IRestrictedContentProvider encapsulatedContentProvider : encapsulatedContentProviders) {
+ Object[] directElements = encapsulatedContentProvider.getChildren(parentElement);
+ if (directElements != null && directElements.length != 0) {
+ asList.addAll(Arrays.asList(directElements));
+ }
+ }
+ return asList.toArray();
+ }
+
+
+ @Override
+ public Object getParent(Object element) {
+ for (IRestrictedContentProvider encapsulatedContentProvider : encapsulatedContentProviders) {
+ Object parent = encapsulatedContentProvider.getParent(element);
+ if (parent != null) {
+ return parent;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return true;
+ }
+
+
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ this.encapsulatedContentProviders.clear();
+ }
+
+ @Override
+ public void setRestriction(boolean isRestricted) {
+ for (IRestrictedContentProvider current : encapsulatedContentProviders) {
+ current.setRestriction(isRestricted);
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IRestrictedContentProvider#isRestricted()
+ *
+ * @return
+ */
+ @Override
+ public boolean isRestricted() {
+ if (!encapsulatedContentProviders.isEmpty()) {
+ return encapsulatedContentProviders.get(0).isRestricted();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ boolean result = false;
+ for (final IRestrictedContentProvider current : encapsulatedContentProviders) {
+ result = result || current.isValidValue(element);
+ }
+ return result;
+ }
+
+ @Override
+ public Object[] getElements() {
+ return getElements(null);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#setIgnoreInheritedElements(boolean)
+ *
+ * @param ignoreInheritedElements
+ */
+ @Override
+ public void setIgnoreInheritedElements(boolean ignoreInheritedElements) {
+ for (final IRestrictedContentProvider current : encapsulatedContentProviders) {
+ current.setIgnoreInheritedElements(ignoreInheritedElements);
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#isIgnoringInheritedElements()
+ *
+ * @return
+ */
+ @Override
+ public boolean isIgnoringInheritedElements() {
+ return encapsulatedContentProviders.get(0).isIgnoringInheritedElements();// the value is the same for all encapsulated content provider
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingLabelProvider.java
new file mode 100644
index 00000000000..cdfdef64464
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingLabelProvider.java
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST, Christian W. Damus, 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:
+ * CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 399859
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A label provider that delegates to some other label provider with the
+ * possibility of overriding certain labels.
+ */
+public class DelegatingLabelProvider
+ extends LabelProvider {
+
+ private final ILabelProvider delegate;
+ private ILabelProviderListener forwardingListener;
+
+ public DelegatingLabelProvider(ILabelProvider delegate) {
+ super();
+
+ this.delegate = delegate;
+
+ delegate.addListener(getForwardingListener());
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ Image result = customGetImage(element);
+ if (result == null) {
+ result = delegatedGetImage(element);
+ }
+ return result;
+ }
+
+ /**
+ * Overridden in subclasses to provide custom images for certain {@code element}s.
+ *
+ * @param element
+ * an element
+ * @return the custom image, or {@code null} to delegate
+ */
+ protected Image customGetImage(Object element) {
+ return null;
+ }
+
+ protected Image delegatedGetImage(Object element) {
+ return delegate.getImage(element);
+ }
+
+ @Override
+ public String getText(Object element) {
+ String result = customGetText(element);
+ if (result == null) {
+ result = delegatedGetText(element);
+ }
+ return result;
+ }
+
+ /**
+ * Overridden in subclasses to provide custom text for certain {@code element}s.
+ *
+ * @param element
+ * an element
+ * @return the custom text, or {@code null} to delegate
+ */
+ protected String customGetText(Object element) {
+ return null;
+ }
+
+ protected String delegatedGetText(Object element) {
+ return delegate.getText(element);
+ }
+
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return delegate.isLabelProperty(element, property);
+ }
+
+ @Override
+ public void addListener(ILabelProviderListener listener) {
+ delegate.addListener(listener);
+ }
+
+ @Override
+ public void removeListener(ILabelProviderListener listener) {
+ delegate.removeListener(listener);
+ }
+
+ /**
+ * Disposes my delegate.
+ */
+ @Override
+ public void dispose() {
+ delegate.removeListener(getForwardingListener());
+ delegate.dispose();
+ }
+
+ private ILabelProviderListener getForwardingListener() {
+ if (forwardingListener == null) {
+ forwardingListener = new ILabelProviderListener() {
+
+ @Override
+ public void labelProviderChanged(LabelProviderChangedEvent event) {
+ fireLabelProviderChanged(new LabelProviderChangedEvent(DelegatingLabelProvider.this, event.getElements()));
+ }
+ };
+ }
+
+ return forwardingListener;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingStyledLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingStyledLabelProvider.java
new file mode 100644
index 00000000000..b08a0ac5b89
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/DelegatingStyledLabelProvider.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Christian W. Damus 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+
+/**
+ * A styled label provider that delegates to another styled label provider with the option to override certain labels.
+ */
+public class DelegatingStyledLabelProvider extends DelegatingLabelProvider implements IStyledLabelProvider {
+
+ private final IStyledLabelProvider delegate;
+
+ public DelegatingStyledLabelProvider(ILabelProvider delegate) {
+ super(delegate);
+
+ if (!(delegate instanceof IStyledLabelProvider)) {
+ throw new IllegalArgumentException("delegate is not a styled label provider"); //$NON-NLS-1$
+ }
+
+ this.delegate = (IStyledLabelProvider) delegate;
+ }
+
+ @Override
+ public StyledString getStyledText(Object element) {
+ StyledString result = customGetStyledText(element);
+ if (result == null) {
+ result = delegatedGetStyledText(element);
+ }
+ return result;
+ }
+
+ /**
+ * Override in subclasses to return custom styled text to override the delegate.
+ * The default implementation simply returns {@code null}.
+ *
+ * @param element
+ * an element for which to provide styled text
+ * @return the custom styled text, or {@code null} to delegate
+ */
+ protected StyledString customGetStyledText(Object element) {
+ return null;
+ }
+
+ protected final StyledString delegatedGetStyledText(Object element) {
+ return delegate.getStyledText(element);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EmptyContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EmptyContentProvider.java
new file mode 100644
index 00000000000..c0e8ec807f6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EmptyContentProvider.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+
+/**
+ * A ContentProvider returning empty collections
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class EmptyContentProvider extends AbstractStaticContentProvider {
+
+ /**
+ * Singleton instance
+ */
+ public static final EmptyContentProvider instance = new EmptyContentProvider();
+
+ private final Object[] value = new Object[0];
+
+ private EmptyContentProvider() {
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider#getElements()
+ *
+ * @return
+ * an empty array
+ */
+ @Override
+ public Object[] getElements() {
+ return value;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EncapsulatedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EncapsulatedContentProvider.java
new file mode 100644
index 00000000000..db678c08437
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/EncapsulatedContentProvider.java
@@ -0,0 +1,305 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST, Christian W. Damus, 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 455075
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.infra.tools.util.ListHelper;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.strategy.IStrategyBasedContentProvider;
+import org.eclipse.papyrus.infra.widgets.strategy.TreeBrowseStrategy;
+import org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A ContentProvider encapsulate another ContentProvider.
+ * This class implements all Papyrus interfaces extending IContentProvider,
+ * and is thus compatible with all papyrus tools, even if the encapsulated
+ * provider is not.
+ *
+ * Moreover, the Encapsulated provider can handle temporary elements.
+ *
+ * @author Camille Letavernier
+ *
+ */
+// TODO : Move the temporary elements feature to another class.
+// This feature is only used by multi-reference dialogs
+public class EncapsulatedContentProvider implements IHierarchicContentProvider, IGraphicalContentProvider, ICommitListener, IAdaptableContentProvider, IRevealSemanticElement, IStrategyBasedContentProvider, IStaticContentProvider {
+
+ /**
+ * The encapsulated static content provider
+ */
+ protected IStructuredContentProvider encapsulated;
+
+ /**
+ * The set of temporaryElements, which are added from outside this ContentProvider
+ */
+ private Set<Object> temporaryElements = new LinkedHashSet<Object>();
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param encapsulated
+ * The encapsulated content provider, to which all calls will be forwarded
+ */
+ public EncapsulatedContentProvider(IStructuredContentProvider encapsulated) {
+ this.encapsulated = encapsulated;
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ protected EncapsulatedContentProvider() {
+ }
+
+ /**
+ * Returns all elements known by this ContentProvider. This is the union of
+ * the objects returned by the wrapped StaticContentProvider and the temporary
+ * elements, which are not known by the wrapped provider.
+ *
+ * @param elements
+ * The Object[] returned by the encapsulated provider
+ * @return
+ * All elements known by this ContentProvider
+ */
+ private Object[] getAllElements(Object[] elements) {
+ if (temporaryElements.isEmpty()) {
+ return elements;
+ }
+
+ List<Object> result = ListHelper.asList(elements);
+ result.addAll(temporaryElements);
+ return result.toArray();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ // encapsulated.dispose();
+ // encapsulated = null;
+ }
+
+ /**
+ * Updates me to encapsulate a new {@code delegate}. If it makes sense for a particular instance, this may
+ * collapse any chain of providers that are exactly of {@link EncapsulatedContentProvider} type (not some
+ * subclass that may have different behaviour). If it is necessary to delegate to another encapsulated
+ * instance as is, then simply assign the protected {@link #encapsulated} field.
+ *
+ * @param delegate
+ * my new delegate, or {@code null} to simply forget the previous delegate
+ */
+ protected void encapsulate(IStructuredContentProvider delegate) {
+ while ((delegate != null) && (delegate.getClass() == EncapsulatedContentProvider.class)) {
+ delegate = ((EncapsulatedContentProvider) delegate).encapsulated;
+ }
+
+ this.encapsulated = delegate;
+ }
+
+ protected void addViewerFilter(StructuredViewer viewer, ViewerFilter filter) {
+ Set<ViewerFilter> currentFilters = new LinkedHashSet<ViewerFilter>(Arrays.asList(viewer.getFilters()));
+ currentFilters.add(filter);
+ viewer.setFilters(currentFilters.toArray(new ViewerFilter[currentFilters.size()]));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (encapsulated != null) {
+ encapsulated.inputChanged(viewer, oldInput, newInput);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (encapsulated == null) {
+ return new Object[0];
+ }
+ return getAllElements(encapsulated.getElements(inputElement));
+ }
+
+ /**
+ * Gets the elements for this content provider
+ *
+ * @return
+ * all elements from the wrapped ContentProvider
+ */
+ @Override
+ public Object[] getElements() {
+ if (encapsulated instanceof IStaticContentProvider) {
+ return getAllElements(((IStaticContentProvider) encapsulated).getElements());
+ }
+ return getElements(null);
+ }
+
+ /**
+ * Adds a Temporary element to this ContentProvider
+ *
+ * @param newObject
+ * The temporary element to be added
+ */
+ public void addTemporaryElement(Object newObject) {
+ temporaryElements.add(newObject);
+ }
+
+ /**
+ * Removes a Temporary element from this ContentProvider
+ *
+ * @param removeObject
+ * The temporary element to remove
+ */
+ public void removeTemporaryElement(Object removeObject) {
+ temporaryElements.remove(removeObject);
+ }
+
+ /**
+ * Clears all temporary elements from this content provider
+ */
+ public void clearTemporaryElements() {
+ temporaryElements.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (encapsulated instanceof ITreeContentProvider) {
+ return ((ITreeContentProvider) encapsulated).getChildren(parentElement);
+ } else {
+ return new Object[0];
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getParent(Object element) {
+ if (encapsulated instanceof ITreeContentProvider) {
+ return ((ITreeContentProvider) encapsulated).getParent(element);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ if (encapsulated instanceof ITreeContentProvider) {
+ return ((ITreeContentProvider) encapsulated).hasChildren(element);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isValidValue(Object element) {
+ if (encapsulated instanceof IHierarchicContentProvider) {
+ return ((IHierarchicContentProvider) encapsulated).isValidValue(element);
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createBefore(Composite parent) {
+ if (encapsulated instanceof IGraphicalContentProvider) {
+ ((IGraphicalContentProvider) encapsulated).createBefore(parent);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createAfter(Composite parent) {
+ if (encapsulated instanceof IGraphicalContentProvider) {
+ ((IGraphicalContentProvider) encapsulated).createAfter(parent);
+ }
+ }
+
+ @Override
+ public void commit(AbstractEditor editor) {
+ if (encapsulated instanceof ICommitListener) {
+ ((ICommitListener) encapsulated).commit(editor);
+ }
+ }
+
+ @Override
+ public Object getAdaptedValue(Object selection) {
+ if (encapsulated instanceof IAdaptableContentProvider) {
+ return ((IAdaptableContentProvider) encapsulated).getAdaptedValue(selection);
+ }
+ return selection;
+ }
+
+ @Override
+ public void revealSemanticElement(List<?> elementList) {
+ if (encapsulated instanceof IRevealSemanticElement) {
+ ((IRevealSemanticElement) encapsulated).revealSemanticElement(elementList);
+ } else if (encapsulated instanceof CompositeContentProvider) {
+ if (((CompositeContentProvider) encapsulated).getContentProviders() != null) {
+ for (ITreeContentProvider contentProvider : ((CompositeContentProvider) encapsulated).getContentProviders()) {
+ if (contentProvider instanceof IRevealSemanticElement) {
+ ((IRevealSemanticElement) contentProvider).revealSemanticElement(elementList);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public TreeBrowseStrategy getBrowseStrategy() {
+ if (encapsulated instanceof IStrategyBasedContentProvider) {
+ return ((IStrategyBasedContentProvider) encapsulated).getBrowseStrategy();
+ }
+ return null;
+ }
+
+ @Override
+ public TreeBrowseStrategy getRevealStrategy() {
+ if (encapsulated instanceof IStrategyBasedContentProvider) {
+ return ((IStrategyBasedContentProvider) encapsulated).getRevealStrategy();
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FileExtensions.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FileExtensions.java
new file mode 100644
index 00000000000..230efa8981d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FileExtensions.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Standard file extensions used in Papyrus
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class FileExtensions {
+
+ public static final Map<String, String> umlExtensions = new LinkedHashMap<String, String>();
+
+ public static final Map<String, String> umlProfileExtensions = new LinkedHashMap<String, String>();
+
+ public static final Map<String, String> cssStylesheetsExtension = new LinkedHashMap<String, String>();
+
+ public static final Map<String, String> allFilesExtensions = new LinkedHashMap<String, String>();
+
+ static {
+ umlExtensions.put("*.uml", "UML (*.uml)"); //$NON-NLS-1$ //$NON-NLS-2$
+ umlExtensions.put("*.profile.uml", "UML Profiles (*.profile.uml)"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ umlProfileExtensions.put("*.profile.uml", "UML Profiles (*.profile.uml)"); //$NON-NLS-1$ //$NON-NLS-2$
+ umlProfileExtensions.put("*.uml", "UML (*.uml)"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ cssStylesheetsExtension.put("*.css", "CSS Stylesheets (*.css)"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ allFilesExtensions.put("*", "All (*)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FilteredContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FilteredContentProvider.java
new file mode 100644
index 00000000000..a400c8bbf91
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FilteredContentProvider.java
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.editors.StringEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * A generic implementation for a IGraphicalContentProvider.
+ * This class doesn't provide any element, and should be extended.
+ *
+ * It implements a filter for List or Tree elements, based on the label
+ * provided by the viewer's label provider (Or Object#toString() if the viewer
+ * doesn't have a label provider).
+ *
+ * A Text widget is added before the display control to insert the filter
+ * pattern. An element is matched if at least one of these conditions is
+ * matched :
+ * - The element's name matches the pattern
+ * - One of the element's children matches the pattern
+ * - One of the element's parent matches the pattern
+ *
+ * The elements' hierarchy is obtained via the viewer's ContentProvider.
+ *
+ * @author Camille Letavernier
+ */
+public class FilteredContentProvider extends EncapsulatedContentProvider {
+
+ protected StructuredViewer viewer;
+
+ private StringEditor filterPattern;
+
+ private PatternViewerFilter filter;
+
+ public static final String BASE_PATTERN = "*"; //$NON-NLS-1$
+
+ protected boolean showIfHasVisibleParent = false;
+
+ public FilteredContentProvider(IStructuredContentProvider encapsulated) {
+ super(encapsulated);
+ }
+
+ public FilteredContentProvider() {
+ super();
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ if (viewer instanceof StructuredViewer) {
+ this.viewer = (StructuredViewer) viewer;
+ updateFilter();
+ }
+ }
+
+ private void updateFilter() {
+ if (this.viewer != null && filterPattern != null) {
+ addViewerFilter(viewer, filter);
+ }
+ }
+
+ @Override
+ public void createBefore(Composite parent) {
+ super.createBefore(parent);
+ filterPattern = new StringEditor(parent, SWT.NONE, "Filter: ");
+ filterPattern.setValidateOnDelay(true);
+ filterPattern.setValue(BASE_PATTERN);
+ filter = getViewerFilter();
+ filterPattern.addCommitListener(new ICommitListener() {
+
+ @Override
+ public void commit(AbstractEditor editor) {
+ filter.setPattern((String) filterPattern.getValue());
+ if (viewer != null) {
+ viewer.refresh();
+ }
+ }
+
+ });
+ updateFilter();
+ }
+
+ protected PatternViewerFilter getViewerFilter() {
+ PatternViewerFilter filter = new PatternViewerFilter();
+ filter.setStrict(false);
+ filter.setPattern(BASE_PATTERN);
+ filter.setShowIfHasVisibleParent(showIfHasVisibleParent);
+ return filter;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FlattenableRestrictedFilteredContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FlattenableRestrictedFilteredContentProvider.java
new file mode 100644
index 00000000000..cc79b0ba368
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/FlattenableRestrictedFilteredContentProvider.java
@@ -0,0 +1,203 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Juan Cadavid (CEA LIST) juan.cadavid@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ * @author JC236769
+ *
+ */
+public class FlattenableRestrictedFilteredContentProvider extends AbstractFilteredContentProvider implements IStaticContentProvider, IRestrictedContentProvider, IFlattenableContentProvider {
+
+ private boolean isFlat = false;
+
+ private ReferenceSelector selector;
+
+ protected IRestrictedContentProvider provider;
+
+ protected HierarchicToFlatContentProvider flatProvider;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param provider
+ * the encapsulated content provider
+ * @param selector
+ * the reference selector (we need it to refresh it)
+ */
+ public FlattenableRestrictedFilteredContentProvider(IRestrictedContentProvider provider, ReferenceSelector selector) {
+ this.provider = provider;
+ flatProvider = new HierarchicToFlatContentProvider(provider);
+ this.selector = selector;
+ }
+
+ /**
+ * Add 2 checkboxes to the dialog
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.AbstractFilteredContentProvider#createAfter(org.eclipse.swt.widgets.Composite)
+ *
+ * @param parent
+ */
+ @Override
+ public void createAfter(final Composite parent) {
+
+ super.createAfter(parent);
+ Composite checkboxSection = new Composite(parent, SWT.NONE);
+ checkboxSection.setLayout(new FillLayout(SWT.VERTICAL));
+ final Button onlyCurrentContainersCheckbox = new Button(checkboxSection, SWT.CHECK);
+ onlyCurrentContainersCheckbox.setText(Messages.FlattenableRestrictedFilteredContentProvider_AllPossibleContentsMessage);
+
+ final Button showFlatListOfFeaturesCheckbox = new Button(checkboxSection, SWT.CHECK);
+ showFlatListOfFeaturesCheckbox.setText(Messages.FlattenableRestrictedFilteredContentProvider_FlatViewMessage);
+ onlyCurrentContainersCheckbox.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setRestriction(!onlyCurrentContainersCheckbox.getSelection());
+ viewer.refresh();
+ selector.refresh();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+ showFlatListOfFeaturesCheckbox.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+
+ setFlat(showFlatListOfFeaturesCheckbox.getSelection());
+ viewer.refresh();
+ selector.refresh();
+
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (isFlat) {
+ return flatProvider.getElements(inputElement);
+ }
+ return provider.getElements(inputElement);
+ }
+
+ @Override
+ public void dispose() {
+ flatProvider.dispose();
+ provider.dispose();
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ flatProvider.inputChanged(viewer, oldInput, newInput);
+ provider.inputChanged(viewer, oldInput, newInput);
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ return provider.isValidValue(element);
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (isFlat) {
+ return new Object[0];
+ }
+ return provider.getChildren(parentElement);
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ if (isFlat) {
+ return null;
+ }
+ return provider.getParent(element);
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ if (isFlat) {
+ return false;
+ }
+ return provider.hasChildren(element);
+ }
+
+ @Override
+ public void setRestriction(boolean isRestricted) {
+ provider.setRestriction(isRestricted);
+ }
+
+ @Override
+ public void setFlat(boolean flat) {
+ this.isFlat = flat;
+
+ }
+
+ @Override
+ public Object[] getElements() {
+ return null;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#setIgnoreInheritedElements(boolean)
+ *
+ * @param ignoreInheritedElements
+ */
+ @Override
+ public void setIgnoreInheritedElements(boolean ignoreInheritedElements) {
+ provider.setIgnoreInheritedElements(ignoreInheritedElements);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IInheritedElementContentProvider#isIgnoringInheritedElements()
+ *
+ * @return
+ */
+ @Override
+ public boolean isIgnoringInheritedElements() {
+ return provider.isIgnoringInheritedElements();
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IRestrictedContentProvider#isRestricted()
+ *
+ * @return
+ */
+ @Override
+ public boolean isRestricted() {
+ return provider.isRestricted();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/HierarchicToFlatContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/HierarchicToFlatContentProvider.java
new file mode 100644
index 00000000000..75b7a51b148
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/HierarchicToFlatContentProvider.java
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.Viewer;
+
+//FIXME : Adapt this code to TreeBrowseStrategy
+public class HierarchicToFlatContentProvider extends TreeToFlatContentProvider {
+
+ protected IHierarchicContentProvider contentProvider;
+
+ public HierarchicToFlatContentProvider(IHierarchicContentProvider provider) {
+ super(provider);
+ if (!(provider instanceof IStaticContentProvider)) {
+ throw new IllegalArgumentException();
+ }
+ contentProvider = provider;
+ }
+
+ @Override
+ public void dispose() {
+ contentProvider.dispose();
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ contentProvider.inputChanged(viewer, oldInput, newInput);
+ }
+
+ @Override
+ protected Collection<Object> getElementsList() {
+ Collection<Object> result = new LinkedHashSet<Object>();
+ Set<Object> browsedElements = new HashSet<Object>();
+
+ for (Object root : ((IStaticContentProvider) contentProvider).getElements()) {
+ if (exploreBranch(null, root)) {
+ if (contentProvider.isValidValue(root)) {
+ result.add(getValue(root));
+ }
+ getElementsList(root, result, browsedElements);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void getElementsList(Object parent, Collection<Object> result, Set<Object> browsedElements) {
+ if (!browsedElements.add(parent)) {
+ return;
+ }
+
+ Object[] children = contentProvider.getChildren(parent);
+ if (children == null) {
+ return;
+ }
+
+ for (Object child : children) {
+ Object childValue = getValue(child);
+ if (result.contains(childValue)) {
+ continue; // Avoid infinite recursion
+ }
+ if (exploreBranch(parent, child)) {
+ if (contentProvider.isValidValue(child)) {
+ result.add(childValue);
+ }
+ getElementsList(child, result, browsedElements);
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IAdaptableContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IAdaptableContentProvider.java
new file mode 100644
index 00000000000..a277766a9a9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IAdaptableContentProvider.java
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+/**
+ * A content provider that can be adapted from container value
+ * to semantic value. Useful when you want to display wrapped
+ * values, but still keep an access to the actual semantic values
+ *
+ * @author Camille Letavernier
+ */
+public interface IAdaptableContentProvider extends IStructuredContentProvider {
+
+ /**
+ * Returns the semantic Object contained in the given selection
+ *
+ * @param containerElement
+ * @return
+ * The semantic element contained in the given containerElement
+ */
+ public Object getAdaptedValue(Object containerElement);
+
+ /**
+ * Return an object wrapping the given semanticElement
+ *
+ * @param semanticElement
+ * @return
+ * The container object wrapping the semantic element
+ */
+ // public Object getContainerValue(Object semanticElement);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ICompositeContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ICompositeContentProvider.java
new file mode 100644
index 00000000000..0804e6efaa9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/ICompositeContentProvider.java
@@ -0,0 +1,22 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+
+
+public interface ICompositeContentProvider extends IHierarchicContentProvider {
+
+ public void appendContentProvider(ITreeContentProvider treeContentProvider);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IFlattenableContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IFlattenableContentProvider.java
new file mode 100644
index 00000000000..cd274e712f2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IFlattenableContentProvider.java
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Juan Cadavid (CEA LIST) juan.cadavid@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+/**
+ *
+ * Interfaces for a content provider which can be flat or not
+ *
+ */
+public interface IFlattenableContentProvider {
+
+ /**
+ *
+ * @param isFlat
+ * <code>true</code> if we display the possible value as a flat view
+ */
+ public void setFlat(boolean isFlat);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IGraphicalContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IGraphicalContentProvider.java
new file mode 100644
index 00000000000..8015b5db800
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IGraphicalContentProvider.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * An interface for implementing a ContentProvider which requires
+ * graphical elements for features such as filters.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IGraphicalContentProvider extends IContentProvider {
+
+ /**
+ * Create graphical elements, which will appear before the widget
+ * used to display the provided elements
+ *
+ * @param parent
+ */
+ public abstract void createBefore(Composite parent);
+
+ /**
+ * Create graphical elements, which will appear after the widget
+ * used to display the provided elements
+ *
+ * @param parent
+ */
+ public abstract void createAfter(Composite parent);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IHierarchicContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IHierarchicContentProvider.java
new file mode 100644
index 00000000000..7da7d3b9d55
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IHierarchicContentProvider.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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+
+/**
+ * A Hierarchic content provider. In some cases, we want to be able to display
+ * elements as a Tree, but we are only interested in some specific elements.
+ * The other ones are displayed only to show the hierarchy.
+ * This interface allows the user to specify which elements he is interested
+ * in.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IHierarchicContentProvider extends ITreeContentProvider {
+
+ /**
+ * Indicates if the given is a valid value. Only valid values can be
+ * chosen.
+ *
+ * @param element
+ * The element to test
+ * @return
+ * True if the element is a valid value
+ */
+ public boolean isValidValue(Object element);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IInheritedElementContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IInheritedElementContentProvider.java
new file mode 100644
index 00000000000..130ec453193
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IInheritedElementContentProvider.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+/**
+ * This interface
+ *
+ * @author vl222926
+ *
+ */
+public interface IInheritedElementContentProvider extends IStructuredContentProvider {
+
+ /**
+ *
+ * @param ignoreInheritedElements
+ * if <code>true</code> the inherited elements won't be returned
+ */
+ public void setIgnoreInheritedElements(final boolean ignoreInheritedElements);
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the content provider is ignoring the inherited elements
+ */
+ public boolean isIgnoringInheritedElements();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IRestrictedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IRestrictedContentProvider.java
new file mode 100644
index 00000000000..ed7333329ff
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IRestrictedContentProvider.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Juan Cadavid (CEA LIST) juan.cadavid@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+
+/**
+ * Add a boolean to choose the display mode :
+ * <ul>
+ * <li>display all possible values according to the model (restricted==false)</li>
+ * <li>display all possible values according to current edited object (restricted==true)</li>
+ * </ul>
+ *
+ * @author JC236769
+ *
+ */
+public interface IRestrictedContentProvider extends IHierarchicContentProvider, IStaticContentProvider, IInheritedElementContentProvider {
+
+ /**
+ *
+ * @param isRestricted
+ */
+ public void setRestriction(boolean isRestricted);
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the content provider is restricted
+ */
+ public boolean isRestricted();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IStaticContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IStaticContentProvider.java
new file mode 100644
index 00000000000..75b726009e0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/IStaticContentProvider.java
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+/**
+ * A ContentProvider which returns values that don't depend
+ * on an input value
+ *
+ * In most cases, you should extend the Abstract implementation {@link AbstractStaticContentProvider}
+ *
+ * @author Camille Letavernier
+ *
+ * @see AbstractStaticContentProvider
+ *
+ */
+public interface IStaticContentProvider extends IStructuredContentProvider {
+
+ /**
+ * @return the elements provided by this class
+ */
+ public Object[] getElements();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/MapLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/MapLabelProvider.java
new file mode 100644
index 00000000000..43c3a4ad795
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/MapLabelProvider.java
@@ -0,0 +1,25 @@
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import java.util.Map;
+
+import org.eclipse.jface.viewers.LabelProvider;
+
+/**
+ * A LabelProvider based on a Map
+ *
+ * @author Camille Letavernier
+ */
+public class MapLabelProvider extends LabelProvider {
+
+ protected final Map<Object, String> objectsToLabels;
+
+ public MapLabelProvider(Map<Object, String> objectsToLabels) {
+ this.objectsToLabels = objectsToLabels;
+ }
+
+ @Override
+ public String getText(Object element) {
+ return objectsToLabels.get(element);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/PatternViewerFilter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/PatternViewerFilter.java
new file mode 100644
index 00000000000..ee7080a20f4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/PatternViewerFilter.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.internal.misc.StringMatcher;
+
+/**
+ * A ViewerFilter which can be used to match a pattern.
+ *
+ * The pattern accepts wildcards (* and ?), and ; as a pattern-separator
+ *
+ * For example:
+ * foo;bar will match either "foo" or "bar"
+ * foo* will match "foobar"
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class PatternViewerFilter extends AbstractTreeFilter {
+
+ private StringMatcher[] validPatterns = new StringMatcher[] { new StringMatcher("*", true, false) };
+
+ private String currentPattern;
+
+ private boolean strict = false;
+
+ /**
+ * If the pattern is not strict, wildcards (*) will be added at the beginning and the end of the pattern
+ * The pattern foo becomes equivalent to *foo*
+ *
+ * @param strict
+ */
+ public void setStrict(boolean strict) {
+ this.strict = strict;
+ }
+
+ public void setPattern(String value) {
+ if (value.equals(currentPattern)) {
+ return;
+ }
+
+ currentPattern = value;
+
+ String[] patterns = value.split(";");
+ this.validPatterns = new StringMatcher[patterns.length];
+ int i = 0;
+ for (String pattern : patterns) {
+ if (!strict) {
+ pattern = "*" + pattern.trim() + "*";
+ }
+ validPatterns[i++] = new StringMatcher(pattern, true, false);
+ }
+
+ clearCache();
+ }
+
+ @Override
+ public boolean isVisible(Viewer viewer, Object parentElement, Object element) {
+ IBaseLabelProvider labelProvider = ((StructuredViewer) viewer).getLabelProvider();
+ if (labelProvider instanceof ILabelProvider) {
+ for (StringMatcher pattern : validPatterns) {
+ if (pattern.match(((ILabelProvider) labelProvider).getText(element))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/SemanticWorkspaceContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/SemanticWorkspaceContentProvider.java
new file mode 100644
index 00000000000..41a41e2fe65
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/SemanticWorkspaceContentProvider.java
@@ -0,0 +1,151 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.providers;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.papyrus.infra.tools.util.ListHelper;
+import org.eclipse.papyrus.infra.widgets.Activator;
+
+import com.ibm.icu.text.Collator;
+
+/**
+ * A ContentProvider for resources located in the current workspace
+ *
+ * @author Camille Letavernier
+ */
+public class SemanticWorkspaceContentProvider extends AbstractStaticContentProvider implements IHierarchicContentProvider {
+
+ /**
+ * Constructor
+ */
+ public SemanticWorkspaceContentProvider() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getElements() {
+ try {
+ return filterAccessibleElements(ResourcesPlugin.getWorkspace().getRoot().members());
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ return new Object[0];
+ }
+ }
+
+ protected Object[] filterAccessibleElements(IResource[] members) {
+ List<IResource> accessibleElements = ListHelper.asList(members);
+
+ Iterator<IResource> resourceIterator = accessibleElements.iterator();
+ while (resourceIterator.hasNext()) {
+ IResource resource = resourceIterator.next();
+ if (!resource.isAccessible()) {
+ resourceIterator.remove();
+ }
+ }
+
+ Collections.sort(accessibleElements, resourceComparator);
+
+ return accessibleElements.toArray();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof IContainer) {
+ try {
+ IResource[] members = ((IContainer) parentElement).members();
+
+ return filterAccessibleElements(members);
+ } catch (CoreException ex) {
+ Activator.log.error(ex);
+ }
+ }
+ return new Object[0];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getParent(Object element) {
+ if (element instanceof IContainer) {
+ return ((IContainer) element).getParent();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isValidValue(Object element) {
+ return !(element instanceof IWorkspaceRoot);
+ }
+
+ /**
+ * Compares two resources (IResource)
+ */
+ private static final Comparator<IResource> resourceComparator = createComparator();
+
+ private static Comparator<IResource> createComparator() {
+ final int folderTypes = IResource.FOLDER | IResource.PROJECT | IResource.ROOT;
+ return new Comparator<IResource>() {
+
+ @Override
+ public int compare(IResource resource1, IResource resource2) {
+ int typeCompare = compareType(resource1, resource2);
+ if (typeCompare == 0) {
+ return compareName(resource1, resource2);
+ }
+ return typeCompare;
+ }
+
+ private int compareType(IResource resource1, IResource resource2) {
+ if (resource1.getType() == resource2.getType()) {
+ return 0;
+ }
+ if ((resource1.getType() & folderTypes) > (resource2.getType() & folderTypes)) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ private int compareName(IResource resource1, IResource resource2) {
+ return Collator.getInstance().compare(resource1.getName(), resource2.getName());
+ }
+
+ };
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/StaticContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/StaticContentProvider.java
new file mode 100644
index 00000000000..171aaf58450
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/StaticContentProvider.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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Default implementation of IStaticContentProvider, creating a ContentProvider
+ * from an Array of objects.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class StaticContentProvider extends AbstractStaticContentProvider {
+
+ /**
+ * The elements for this content provider
+ */
+ private Object[] elements;
+
+ /**
+ * The JFace viewer on which this content provider is applied
+ */
+ private Viewer viewer;
+
+ /**
+ *
+ * Constructor. Creates a new ContentProvider with the given elements
+ *
+ * @param elements
+ * The elements known by this ContentProvider
+ */
+ public StaticContentProvider(Object[] elements) {
+ this.elements = elements;
+ }
+
+ /**
+ * Changes the elements known by this ContentProvider
+ *
+ * @param elements
+ * The elements known by this ContentProvider
+ */
+ public void setElements(Object[] elements) {
+ this.elements = elements;
+ if (viewer != null) {
+ viewer.refresh();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ this.viewer = viewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getElements() {
+ return elements;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeCollectionContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeCollectionContentProvider.java
new file mode 100644
index 00000000000..73deef70ce1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeCollectionContentProvider.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import java.util.Collection;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+public class TreeCollectionContentProvider implements ITreeContentProvider {
+
+ private TreeCollectionContentProvider() {
+
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return new Object[0];
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ public static final TreeCollectionContentProvider instance = new TreeCollectionContentProvider();
+
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Nothing
+ }
+
+ /**
+ * Converts the input List to an Array containing the same elements
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ *
+ * @param inputElement
+ * @return
+ * The Array containing the input elements
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof Collection) {
+ return ((Collection<?>) inputElement).toArray();
+ } else if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ }
+
+ return new Object[] {};
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeToFlatContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeToFlatContentProvider.java
new file mode 100644
index 00000000000..680cb658b10
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/TreeToFlatContentProvider.java
@@ -0,0 +1,112 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+//FIXME : Adapt this code to TreeBrowseStrategy
+public class TreeToFlatContentProvider extends AbstractStaticContentProvider {
+
+ private ITreeContentProvider contentProvider;
+
+ private StructuredViewer viewer;
+
+ public TreeToFlatContentProvider(ITreeContentProvider provider) {
+ if (!(provider instanceof IStaticContentProvider)) {
+ throw new IllegalArgumentException();
+ }
+ this.contentProvider = provider;
+ }
+
+ @Override
+ public void dispose() {
+ contentProvider.dispose();
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (viewer instanceof StructuredViewer) {
+ this.viewer = (StructuredViewer) viewer;
+ }
+
+ contentProvider.inputChanged(viewer, oldInput, newInput);
+ }
+
+ @Override
+ public Object[] getElements() {
+ return getElementsList().toArray();
+ }
+
+ /**
+ * Returns the concrete value from the given Object
+ * For example, if the content provider is an IAdaptableContentProvider,
+ * returns the adapted value.
+ *
+ * @param value
+ * @return
+ */
+ protected Object getValue(Object value) {
+ if (contentProvider instanceof IAdaptableContentProvider) {
+ return ((IAdaptableContentProvider) contentProvider).getAdaptedValue(value);
+ } else {
+ return value;
+ }
+ }
+
+ protected boolean exploreBranch(Object parentElement, Object element) {
+ if (viewer == null) {
+ return true;
+ }
+
+ for (ViewerFilter filter : viewer.getFilters()) {
+ if (!filter.select(viewer, parentElement, element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected Collection<Object> getElementsList() {
+ Collection<Object> result = new LinkedHashSet<Object>();
+ Set<Object> browsedElements = new HashSet<Object>();
+
+ for (Object root : ((IStaticContentProvider) contentProvider).getElements()) {
+ if (exploreBranch(null, root)) {
+ result.add(root);
+ getElementsList(root, result, browsedElements);
+ }
+ }
+
+ return result;
+ }
+
+ protected void getElementsList(Object parent, Collection<Object> result, Set<Object> browsedElements) {
+ for (Object child : contentProvider.getChildren(parent)) {
+ Object childValue = getValue(child);
+ if (!result.contains(childValue)) { // Avoid infinite recursion
+ result.add(childValue);
+ if (exploreBranch(parent, child)) {
+ getElementsList(child, result, browsedElements);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnchangedObject.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnchangedObject.java
new file mode 100644
index 00000000000..a6369991fa1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnchangedObject.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.infra.widgets.providers;
+
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+
+public class UnchangedObject {
+
+ private UnchangedObject() {
+
+ }
+
+ @Override
+ public String toString() {
+ return Messages.ReferenceDialogObservable_Unchanged;
+ }
+
+ public static final UnchangedObject instance = new UnchangedObject();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnsetObject.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnsetObject.java
new file mode 100644
index 00000000000..897a36d56a1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/UnsetObject.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.infra.widgets.providers;
+
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+
+public class UnsetObject {
+
+ @Override
+ public String toString() {
+ return Messages.ReferenceDialog_Unset;
+ }
+
+ private UnsetObject() {
+
+ }
+
+ public static final UnsetObject instance = new UnsetObject();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkbenchFilteredLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkbenchFilteredLabelProvider.java
new file mode 100644
index 00000000000..39b05f847ab
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkbenchFilteredLabelProvider.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2012, 2015 CEA LIST, Christian W. Damus, 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 469188
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.providers;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.services.labelprovider.service.IFilteredLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+
+/**
+ * A LabelProvider contribution to handle Workspace elements
+ *
+ * @author Camille Letavernier
+ */
+public class WorkbenchFilteredLabelProvider extends LabelProvider implements IFilteredLabelProvider {
+
+ private final ILabelProvider workbenchLabelProvider;
+
+ public WorkbenchFilteredLabelProvider() {
+ workbenchLabelProvider = WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider();
+ }
+
+ @Override
+ public String getText(Object element) {
+ return workbenchLabelProvider.getText(unwrapSelection(element));
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return workbenchLabelProvider.getImage(unwrapSelection(element));
+ }
+
+ @Override
+ public boolean accept(Object element) {
+ return unwrapSelection(element) instanceof IResource;
+ }
+
+ /**
+ * Unwraps a single selection to get the element inside it.
+ *
+ * @param selection
+ * @return
+ */
+ Object unwrapSelection(Object possibleSelection) {
+ Object result = possibleSelection;
+
+ if (possibleSelection instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) possibleSelection;
+ if (selection.size() == 1) {
+ result = selection.getFirstElement();
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkspaceContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkspaceContentProvider.java
new file mode 100644
index 00000000000..1562e0ea009
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WorkspaceContentProvider.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.providers;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.widgets.strategy.ProviderBasedBrowseStrategy;
+import org.eclipse.papyrus.infra.widgets.strategy.StrategyBasedContentProvider;
+import org.eclipse.papyrus.infra.widgets.strategy.TreeBrowseStrategy;
+import org.eclipse.papyrus.infra.widgets.strategy.WorkspaceRevealStrategy;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * A Workspace content provider with search possibilities and filters (By file name and by file extension)
+ *
+ * @author Camille Letavernier
+ */
+public class WorkspaceContentProvider extends EncapsulatedContentProvider {
+
+ private Map<String, String> extensionFilters = new LinkedHashMap<String, String>();
+
+ private PatternViewerFilter extensionViewerFilter = new PatternViewerFilter();
+
+ private ISelectionChangedListener extensionFiltersListener = new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+
+ String patternString = "*";
+ if (!event.getSelection().isEmpty()) {
+ patternString = (String) ((IStructuredSelection) event.getSelection()).getFirstElement();
+ }
+ extensionViewerFilter.setPattern(patternString);
+ viewer.refresh();
+ }
+ };
+
+ protected StructuredViewer viewer;
+
+ /**
+ * Constructor
+ */
+ public WorkspaceContentProvider() {
+ super();
+ this.encapsulated = encapsulateProvider(getSemanticProvider());
+ extensionFilters.put("*", "All (*)");
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+
+ if (viewer instanceof StructuredViewer) {
+ this.viewer = (StructuredViewer) viewer;
+ addViewerFilter(this.viewer, extensionViewerFilter);
+ }
+ }
+
+ protected static IHierarchicContentProvider getSemanticProvider() {
+ return new SemanticWorkspaceContentProvider();
+ }
+
+ public void setExtensionFilters(Map<String, String> extensionFilters) {
+ this.extensionFilters = extensionFilters;
+ }
+
+ public void addExtensionFilter(String pattern, String label) {
+ this.extensionFilters.put(pattern, label);
+ }
+
+ protected IStructuredContentProvider encapsulateProvider(IHierarchicContentProvider provider) {
+ TreeBrowseStrategy browseStrategy = new ProviderBasedBrowseStrategy(provider);
+ TreeBrowseStrategy revealStrategy = new WorkspaceRevealStrategy(provider);
+ StrategyBasedContentProvider strategyProvider = new StrategyBasedContentProvider(browseStrategy, revealStrategy);
+
+
+ EncapsulatedContentProvider graphicalProvider = new ExtensionFilteredContentProvider(strategyProvider);
+
+ return graphicalProvider;
+ }
+
+ private class ExtensionFilteredContentProvider extends FilteredContentProvider {
+
+ public ExtensionFilteredContentProvider(IHierarchicContentProvider semanticProvider) {
+ super(semanticProvider);
+ }
+
+ @Override
+ public void createAfter(Composite parent) {
+ super.createAfter(parent);
+ ComboViewer extensionFiltersViewer = new ComboViewer(parent);
+
+ extensionFiltersViewer.setContentProvider(CollectionContentProvider.instance);
+ extensionFiltersViewer.setLabelProvider(new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (extensionFilters.containsKey(element)) {
+ return extensionFilters.get(element);
+ } else {
+ return super.getText(element);
+ }
+ }
+ });
+
+ extensionFiltersViewer.addSelectionChangedListener(extensionFiltersListener);
+
+ extensionFiltersViewer.setInput(extensionFilters.keySet());
+ if (!extensionFilters.isEmpty()) {
+ extensionFiltersViewer.setSelection(new StructuredSelection(extensionFilters.keySet().iterator().next()));
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WrappedLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WrappedLabelProvider.java
new file mode 100644
index 00000000000..0b6d84d2160
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/WrappedLabelProvider.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * 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.infra.widgets.providers;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A mutable wrapper for {@link ILabelProvider}s
+ * May be used when you need to instantiate a component with a labelProvider,
+ * and you don't have one yet.
+ * If there is no wrapped label provider, the default toString method will be called
+ * on non-null objects.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class WrappedLabelProvider implements ILabelProvider {
+
+ /**
+ * The wrapped LabelProvider
+ */
+ private ILabelProvider labelProvider;
+
+ /**
+ * Constructs a new empty Label provider wrapper.
+ */
+ public WrappedLabelProvider() {
+
+ }
+
+ /**
+ *
+ * Constructs a new Label provider, wrapping the specified label provider.
+ *
+ * @param provider
+ * The wrapped label provider
+ */
+ public WrappedLabelProvider(ILabelProvider provider) {
+ this.labelProvider = provider;
+ }
+
+ /**
+ * Changes the wrapped label provider
+ *
+ * @param provider
+ * The new wrapped label provider
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ this.labelProvider = provider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addListener(ILabelProviderListener listener) {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeListener(ILabelProviderListener listener) {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Image getImage(Object element) {
+ if (labelProvider != null) {
+ return labelProvider.getImage(element);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText(Object element) {
+ if (labelProvider != null) {
+ return labelProvider.getText(element);
+ }
+ if (element == null)
+ {
+ return "null"; //$NON-NLS-1$
+ }
+ return element.toString();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/BooleanSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/BooleanSelector.java
new file mode 100644
index 00000000000..76e56655549
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/BooleanSelector.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.infra.widgets.selectors;
+
+import org.eclipse.papyrus.infra.tools.util.BooleanHelper;
+
+
+
+/**
+ * A Selector for Integer values
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanSelector extends StringSelector {
+
+ /**
+ * Constructs a Selector for Integer values
+ */
+ public BooleanSelector() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Boolean[] getSelectedElements() {
+ Boolean[] result = new Boolean[0];
+ try {
+ if (BooleanHelper.isBoolean(text.getText())) {
+ result = new Boolean[] { new Boolean(text.getText()) };
+ text.setText(""); //$NON-NLS-1$
+ }
+ } catch (NumberFormatException ex) {
+ // nothing to do
+ }
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/IntegerSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/IntegerSelector.java
new file mode 100644
index 00000000000..d53f22ef52b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/IntegerSelector.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * 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.infra.widgets.selectors;
+
+
+/**
+ * A Selector for Integer values
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class IntegerSelector extends StringSelector {
+
+ /**
+ * Constructs a Selector for Integer values
+ */
+ public IntegerSelector() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer[] getSelectedElements() {
+ Integer[] result;
+ try {
+ result = new Integer[] { Integer.parseInt(text.getText()) };
+ text.setText(""); //$NON-NLS-1$
+ } catch (NumberFormatException ex) {
+ result = new Integer[0];
+ }
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/NullSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/NullSelector.java
new file mode 100644
index 00000000000..e8d764bfe34
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/NullSelector.java
@@ -0,0 +1,61 @@
+package org.eclipse.papyrus.infra.widgets.selectors;
+
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelectionListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Null implementation of the IElementSelector interface
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class NullSelector implements IElementSelector {
+
+ private NullSelector() {
+
+ }
+
+ @Override
+ public Object[] getSelectedElements() {
+ return new Object[0];
+ }
+
+ @Override
+ public void setSelectedElements(Object[] elements) {
+ // Nothing
+ }
+
+ @Override
+ public Object[] getAllElements() {
+ return new Object[0];
+ }
+
+ @Override
+ public void createControls(Composite parent) {
+ // Nothing
+ }
+
+ @Override
+ public void newObjectCreated(Object newObject) {
+ // Nothing
+ }
+
+ @Override
+ public void clearTemporaryElements() {
+ // Nothing
+ }
+
+ @Override
+ public void addElementSelectionListener(IElementSelectionListener listener) {
+ // Nothing
+ }
+
+ @Override
+ public void removeElementSelectionListener(IElementSelectionListener listener) {
+ // Nothing
+ }
+
+ public final static NullSelector instance = new NullSelector();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/RealSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/RealSelector.java
new file mode 100644
index 00000000000..b12922c959e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/RealSelector.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.selectors;
+
+
+/**
+ * A Selector for Real values
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class RealSelector extends StringSelector {
+
+ /**
+ * Constructs a Selector for Real values
+ */
+ public RealSelector() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Double[] getSelectedElements() {
+ Double[] result;
+ try {
+ result = new Double[] { Double.parseDouble((text.getText())) };
+ text.setText(""); //$NON-NLS-1$
+ } catch (NumberFormatException ex) {
+ result = new Double[0];
+ }
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/ReferenceSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/ReferenceSelector.java
new file mode 100644
index 00000000000..9522a9364c0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/ReferenceSelector.java
@@ -0,0 +1,436 @@
+/*****************************************************************************
+ * 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.infra.widgets.selectors;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelectionListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IGraphicalContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.infra.widgets.strategy.ProviderBasedBrowseStrategy;
+import org.eclipse.papyrus.infra.widgets.strategy.StrategyBasedContentProvider;
+import org.eclipse.papyrus.infra.widgets.strategy.TreeBrowseStrategy;
+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;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+
+/**
+ * A Selector for Multiple Reference values, with a filter
+ *
+ * This selector is compatible with {@link org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider}
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ReferenceSelector implements IElementSelector {
+
+ /**
+ * The tree viewer
+ */
+ protected TreeViewer treeViewer;
+
+ /**
+ * The content provider, returning the available reference values
+ */
+ protected EncapsulatedContentProvider contentProvider;
+
+ /**
+ * The content provider, returning the available reference labels
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * Indicates if the reference values should be unique
+ */
+ protected boolean unique;
+
+ /**
+ * Indicates if this selector should be able to return more than one value
+ * at a time.
+ */
+ protected boolean multiSelection;
+
+
+ protected final List<ICommitListener> commitListeners;
+
+
+ private Set<IElementSelectionListener> elementSelectionListeners = new HashSet<IElementSelectionListener>();
+
+ /**
+ * The set of selected elements. If the selector is marked as "unique",
+ * these elements will be filtered in the Tree.
+ *
+ * The Elements are in their container form
+ */
+ protected Set<Object> selectedElements = new HashSet<Object>();
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param unique
+ * Indicates if the values are unique. If true, they are removed
+ * from the list when they are chosen
+ */
+ public ReferenceSelector(boolean unique) {
+ this.unique = unique;
+ this.multiSelection = true;
+ commitListeners = new LinkedList<ICommitListener>();
+ }
+
+ /**
+ *
+ * Constructor.
+ * Builds a new ReferenceSelector for a single element
+ *
+ */
+ public ReferenceSelector() {
+ this(false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getSelectedElements() {
+ ISelection selection = treeViewer.getSelection();
+
+ if (selection instanceof IStructuredSelection) {
+ Object[] containerElementsToMove = getElementsToMove(((IStructuredSelection) selection).toArray());
+ Object[] semanticElementsToMove = getSemanticElements(containerElementsToMove);
+ addSelectedElements(semanticElementsToMove);
+ return semanticElementsToMove;
+ }
+
+ return new Object[0];
+ }
+
+ /**
+ * This method is used for handling correctly the IAdaptableContentProvider
+ * The objects can be in two different forms :
+ * - The semantic element
+ * - The container element
+ *
+ * This methods returns an array of semantic elements from an array of
+ * container elements. This is useful for retrieving the semantic elements
+ * from a viewer's selection when the viewer uses an IAdaptableContentProvider
+ *
+ * @param containerElements
+ * The array of elements wrapped in their container
+ * @return
+ * The array of semantic elements to be converted
+ *
+ * @see #getContainerElements(Object[])
+ * @see org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider
+ */
+ private Object[] getSemanticElements(Object[] containerElements) {
+ Object[] semanticElements = new Object[containerElements.length];
+ int i = 0;
+ for (Object containerElement : containerElements) {
+ semanticElements[i++] = contentProvider.getAdaptedValue(containerElement);
+ }
+ return semanticElements;
+ }
+
+ /**
+ * Filters the selection to return only the objects that can
+ * be selected, according to the content provider.
+ *
+ * @param selection
+ * The input array to filter
+ * @return
+ * The filtered array
+ *
+ * @see org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider#isValidValue(Object)
+ */
+ protected Object[] getElementsToMove(Object[] selection) {
+ List<Object> elementsToMove = new LinkedList<Object>();
+
+ for (Object element : selection) {
+ if (contentProvider.isValidValue(element)) {
+ elementsToMove.add(element);
+ }
+ }
+
+ notifyCommitListeners();
+ return elementsToMove.toArray();
+ }
+
+ /**
+ * Adds elements to the list of selected elements. If the values are
+ * unique, the specified elements won't be displayed
+ *
+ * @param elements
+ */
+ private void addSelectedElements(Object[] semanticElements) {
+ if (semanticElements.length > 0) {
+ selectedElements.addAll(Arrays.asList(semanticElements));
+ refresh();
+ }
+ }
+
+ /**
+ * Returns all the elements that are currently displayed, i.e. matching
+ * the filter
+ *
+ * {@link IElementSelector#getAllElements()}
+ *
+ * @return all elements matching the filter
+ */
+ @Override
+ public Object[] getAllElements() {
+ // There is no way to retrieve the filteredElements on a FList
+ // We can only retrieve the selected ones
+ // Fix : we select everything, then we return the selection
+ if (contentProvider == null) {
+ return new Object[0];
+ }
+
+ Collection<Object> visibleElements = new LinkedList<Object>();
+ for (TreeItem rootItem : treeViewer.getTree().getItems()) {
+ visibleElements.add(getElement(rootItem));
+ if (rootItem.getExpanded()) {
+ fillVisibleElements(rootItem, visibleElements);
+ }
+ }
+
+ Object[] containerElementsToMove = getElementsToMove(visibleElements.toArray());
+ Object[] semanticElementsToMove = getSemanticElements(containerElementsToMove);
+ addSelectedElements(semanticElementsToMove);
+
+ return semanticElementsToMove;
+ }
+
+ private void fillVisibleElements(TreeItem item, Collection<Object> visibleElements) {
+ for (TreeItem childItem : item.getItems()) {
+ visibleElements.add(getElement(childItem));
+ if (childItem.getExpanded()) {
+ fillVisibleElements(childItem, visibleElements);
+ }
+ }
+ }
+
+ private Object getElement(TreeItem item) {
+ return item.getData();
+ }
+
+ /**
+ * Sets the list of selected elements. If the values are
+ * unique, the specified elements won't be displayed
+ *
+ * @param elements
+ */
+ @Override
+ public void setSelectedElements(Object[] semanticElements) {
+ selectedElements.clear();
+ selectedElements.addAll(Arrays.asList(semanticElements));
+ refresh();
+ }
+
+ @Override
+ public void newObjectCreated(Object newObject) {
+ contentProvider.addTemporaryElement(newObject);
+ refresh();
+ }
+
+ @Override
+ public void clearTemporaryElements() {
+ contentProvider.clearTemporaryElements();
+ }
+
+ /**
+ * Refreshes this selector's {@link org.eclipse.swt.widgets.List}
+ */
+ public void refresh() {
+ ((SelectionFilteredBrowseStrategy) contentProvider.getBrowseStrategy()).refresh();
+ treeViewer.refresh();
+ }
+
+ /**
+ * Sets this selector's label provider. The label provider is used
+ * to display the reference values
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ if (treeViewer != null) {
+ treeViewer.setLabelProvider(labelProvider);
+ }
+ }
+
+ /**
+ * Sets this selector's content provider. The content provider
+ * is used to select the available values for this property
+ *
+ * @param staticContentProvider
+ */
+ public void setContentProvider(IStaticContentProvider staticContentProvider) {
+
+ ITreeContentProvider provider = new EncapsulatedContentProvider(staticContentProvider);
+
+ TreeBrowseStrategy filteredBrowseStrategy = new SelectionFilteredBrowseStrategy(provider);
+
+ TreeBrowseStrategy revealBrowseStrategy = new ProviderBasedBrowseStrategy(provider);
+
+ this.contentProvider = new StrategyBasedContentProvider(filteredBrowseStrategy, revealBrowseStrategy);
+
+ if (treeViewer != null) {
+ treeViewer.setContentProvider(contentProvider);
+ treeViewer.setInput(""); //$NON-NLS-1$
+ }
+
+ if (contentProvider instanceof ICommitListener) {
+ commitListeners.add(contentProvider);
+ }
+ }
+
+ /**
+ * Strategy to hide tree elements which are already selected, when the selector is defined as unique
+ *
+ * @author Camille Letavernier
+ *
+ */
+ private class SelectionFilteredBrowseStrategy extends ProviderBasedBrowseStrategy {
+
+ public SelectionFilteredBrowseStrategy(ITreeContentProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ if (!unique) {
+ return super.isValidValue(element);
+ }
+
+ if (!super.isValidValue(element)) {
+ return false;
+ }
+
+ return !selectedElements.contains(getAdaptedValue(element));
+ }
+
+ public void refresh() {
+ if (unique) {
+ clearCache();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createControls(Composite parent) {
+ Composite content = new Composite(parent, SWT.NONE);
+ content.setLayout(new GridLayout(1, true));
+
+ treeViewer = new TreeViewer(content, SWT.BORDER | SWT.MULTI);
+ treeViewer.setFilters(new ViewerFilter[] { new PatternFilter() });
+
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.minimumHeight = 300;
+ data.minimumWidth = 300;
+ treeViewer.getTree().setLayoutData(data);
+
+ if (labelProvider != null) {
+ treeViewer.setLabelProvider(labelProvider);
+ }
+
+ if (contentProvider != null) {
+ treeViewer.setContentProvider(contentProvider);
+ treeViewer.setInput(""); //$NON-NLS-1$
+ }
+
+ if (contentProvider instanceof IGraphicalContentProvider) {
+ IGraphicalContentProvider graphicalContentProvider = contentProvider;
+
+ Composite beforeTreeComposite = new Composite(content, SWT.NONE);
+ beforeTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ beforeTreeComposite.setLayout(layout);
+ graphicalContentProvider.createBefore(beforeTreeComposite);
+
+ beforeTreeComposite.moveAbove(treeViewer.getTree());
+
+ Composite afterTreeComposite = new Composite(content, SWT.NONE);
+ layout = new FillLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ afterTreeComposite.setLayout(layout);
+ afterTreeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ graphicalContentProvider.createAfter(afterTreeComposite);
+ }
+
+ // Adds double-click support
+ treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ if (!elementSelectionListeners.isEmpty()) {
+ Object[] selectedElements = getSelectedElements();
+ if (selectedElements.length > 0) {
+ notifyCommitListeners();
+ for (IElementSelectionListener listener : elementSelectionListeners) {
+ listener.addElements(selectedElements);
+ }
+ }
+ }
+ }
+
+ });
+ }
+
+ public void setUnique(boolean unique) {
+ this.unique = unique;
+ }
+
+ @Override
+ public void addElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.add(listener);
+ }
+
+ @Override
+ public void removeElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.remove(listener);
+ }
+
+ protected void notifyCommitListeners() {
+ for (ICommitListener commitListener : commitListeners) {
+ commitListener.commit(null);
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StandardSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StandardSelector.java
new file mode 100644
index 00000000000..5601f20141d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StandardSelector.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.infra.widgets.selectors;
+
+import java.lang.reflect.Constructor;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelectionListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Creates an element selector from an AbstractValueEditor. This class is a
+ * generic implementation for element selectors.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class StandardSelector implements IElementSelector {
+
+ /**
+ * The AbstractValueEditor class used for instantiating this selector
+ */
+ protected Class<? extends AbstractValueEditor> editorClass;
+
+ /**
+ * The AbstractValueEditor used by this selector
+ */
+ protected AbstractValueEditor editor;
+
+ protected Set<IElementSelectionListener> elementSelectionListeners = new HashSet<IElementSelectionListener>();
+
+ /**
+ * Instantiates this selector, using the specified editor class
+ *
+ * @param editorClass
+ * The AbstractValueEditor Class used to instantiate this selector
+ */
+ public StandardSelector(Class<? extends AbstractValueEditor> editorClass) {
+ Assert.isNotNull(editorClass, "The StandardSelector editor class should not be null"); //$NON-NLS-1$
+ this.editorClass = editorClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getSelectedElements() {
+ Object value = editor.getValue();
+ if (value == null) {
+ return new Object[] {};
+ }
+
+ return new Object[] { value };
+ }
+
+ /**
+ * Ignored. The generic selectors can't be filtered.
+ */
+ @Override
+ public void setSelectedElements(Object[] elements) {
+ // Ignored
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getAllElements() {
+ return getSelectedElements();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The control for this selector is obtained by instantiating the generic class with a parent
+ * composite and a default style
+ */
+ @Override
+ public void createControls(Composite parent) {
+ try {
+ Constructor<? extends AbstractValueEditor> construct = editorClass.getDeclaredConstructor(Composite.class, Integer.TYPE);
+ editor = construct.newInstance(parent, SWT.BORDER);
+ editor.addCommitListener(new ICommitListener() {
+
+ @Override
+ public void commit(AbstractEditor editor) {
+ if (!elementSelectionListeners.isEmpty()) {
+ Object value = StandardSelector.this.editor.getValue();
+ for (IElementSelectionListener listener : elementSelectionListeners) {
+ listener.addElements(new Object[] { value });
+ }
+ }
+ }
+
+ });
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+ }
+
+ @Override
+ public void newObjectCreated(Object newObject) {
+ // Ignored
+ }
+
+ @Override
+ public void clearTemporaryElements() {
+ // Ignored
+ }
+
+ @Override
+ public void addElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.add(listener);
+ }
+
+ @Override
+ public void removeElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.remove(listener);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StringSelector.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StringSelector.java
new file mode 100644
index 00000000000..8df015f9b6f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/selectors/StringSelector.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.infra.widgets.selectors;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelectionListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A selector for String values, or values that can be represented
+ * as text in general.
+ * Displays a field where the user can enter the new values.
+ * The field can be multiline or single line
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class StringSelector implements IElementSelector {
+
+ public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ /**
+ * The text box used to enter a value for this selector
+ */
+ protected Text text;
+
+ /**
+ * Indicates if this StringSelector is multiline
+ */
+ protected boolean multiline;
+
+ protected Set<IElementSelectionListener> elementSelectionListeners = new HashSet<IElementSelectionListener>();
+
+ /**
+ * Constructs a single-line String Selector
+ */
+ public StringSelector() {
+ this(false);
+ }
+
+ /**
+ * Constructs a String Selector
+ *
+ * @param multiline
+ * True if the string values can contain more than one line
+ */
+ public StringSelector(boolean multiline) {
+ this.multiline = multiline;
+ }
+
+ /**
+ * Returns a single-element array containing the current text
+ *
+ * {@link IElementSelector#getSelectedElements()}
+ */
+ @Override
+ public Object[] getSelectedElements() {
+ String[] result = new String[] { text.getText() };
+ text.setText(""); //$NON-NLS-1$
+ return result;
+ }
+
+ /**
+ * Ignored
+ */
+ @Override
+ public void setSelectedElements(Object[] elements) {
+ // Nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createControls(Composite parent) {
+ text = new Text(parent, SWT.MULTI | SWT.BORDER);
+ text.addKeyListener(new KeyListener() {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if ((e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) && ((e.stateMask == SWT.NONE && !multiline) || ((e.stateMask & SWT.CTRL) != 0 && multiline))) {
+ if (!elementSelectionListeners.isEmpty()) {
+ String str = (String) getSelectedElements()[0];
+ if (str.endsWith(LINE_SEPARATOR)) {
+ str = str.substring(0, str.length() - LINE_SEPARATOR.length());
+ }
+ if (!"".equals(str)) { //$NON-NLS-1$
+ for (IElementSelectionListener listener : elementSelectionListeners) {
+ listener.addElements(new Object[] { str });
+ }
+ }
+ }
+ }
+ }
+
+ });
+ }
+
+ /**
+ * Returns the same value as getSelectedElements
+ *
+ * {@link IElementSelector#getAllElements()}
+ */
+ @Override
+ public Object[] getAllElements() {
+ return getSelectedElements();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void newObjectCreated(Object newObject) {
+ // Ignored
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearTemporaryElements() {
+ // Ignored
+ }
+
+ @Override
+ public void addElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.add(listener);
+ }
+
+ @Override
+ public void removeElementSelectionListener(IElementSelectionListener listener) {
+ elementSelectionListeners.remove(listener);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/AbstractTreeBrowseStrategy.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/AbstractTreeBrowseStrategy.java
new file mode 100644
index 00000000000..84fc6cb48f8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/AbstractTreeBrowseStrategy.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.Viewer;
+
+
+public abstract class AbstractTreeBrowseStrategy implements TreeBrowseStrategy {
+
+ @Override
+ public void dispose() {
+ // Nothing
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Nothing
+ }
+
+ @Override
+ abstract public void revealSemanticElement(List<?> elementsList);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/IStrategyBasedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/IStrategyBasedContentProvider.java
new file mode 100644
index 00000000000..672e1e85f54
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/IStrategyBasedContentProvider.java
@@ -0,0 +1,22 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+
+public interface IStrategyBasedContentProvider extends IStructuredContentProvider {
+
+ public TreeBrowseStrategy getBrowseStrategy();
+
+ public TreeBrowseStrategy getRevealStrategy();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/ProviderBasedBrowseStrategy.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/ProviderBasedBrowseStrategy.java
new file mode 100644
index 00000000000..9d2136f32c7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/ProviderBasedBrowseStrategy.java
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.tools.util.ListHelper;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider;
+
+
+public class ProviderBasedBrowseStrategy extends EncapsulatedContentProvider implements TreeBrowseStrategy {
+
+ protected ITreeContentProvider provider;
+
+ protected boolean filterElements = false;
+
+ protected final Map<Object, Boolean> cache = new HashMap<Object, Boolean>();
+
+ protected final Map<Object, Boolean> visibleChildCache = new HashMap<Object, Boolean>();
+
+ public ProviderBasedBrowseStrategy(ITreeContentProvider provider) {
+ setProvider(provider);
+ }
+
+ public ProviderBasedBrowseStrategy() {
+
+ }
+
+ public void setProvider(ITreeContentProvider provider) {
+ encapsulated = provider;
+ this.provider = provider;
+ filterElements = provider instanceof IHierarchicContentProvider;
+ clearCache();
+ }
+
+ @Override
+ public Object[] getElements() {
+ return getValidElements(super.getElements());
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getValidElements(super.getElements(inputElement));
+ }
+
+ /**
+ * Filters the valid root elements, ie. the root elements containing
+ * at least one valid child (Or being valid themselves)
+ *
+ * @param roots
+ * @return
+ */
+ protected Object[] getValidElements(Object[] roots) {
+ if (filterElements) {
+ List<Object> rootsList = ListHelper.asList(roots);
+ Iterator<?> iterator = rootsList.iterator();
+ while (iterator.hasNext()) {
+ if (!isValid(iterator.next(), new HashSet<Object>())) {
+ iterator.remove();
+ }
+ }
+ return rootsList.toArray();
+ }
+
+ return roots;
+ }
+
+ @Override
+ public Object[] getChildren(Object parent) {
+ if (provider == null) {
+ Activator.log.warn("The provider has not been initialized");
+ return new Object[0];
+ }
+
+ return getValidElements(super.getChildren(parent));
+ }
+
+ @Override
+ public boolean hasChildren(Object parent) {
+ // May be expensive
+ return getChildren(parent).length > 0;
+ }
+
+ protected boolean isValid(Object containerElement, Set<Object> visitedElements) {
+ if (!cache.containsKey(containerElement)) {
+ boolean isVisible;
+
+ if (browseElement(containerElement)) {
+ isVisible = isValidValue(containerElement) || hasOneVisibleChild(containerElement, visitedElements);
+ } else {
+ isVisible = false;
+ }
+
+ cache.put(containerElement, isVisible);
+ }
+ return cache.get(containerElement);
+ }
+
+ protected boolean browseElement(Object containerElement) {
+ return true;
+ }
+
+ protected boolean hasOneVisibleChild(Object element, Set<Object> visitedElements) {
+ if (!visibleChildCache.containsKey(element)) {
+ boolean result = false;
+ if (visitedElements.add(getAdaptedValue(element))) {
+ for (Object child : super.getChildren(element)) {
+ if (isValid(child, visitedElements)) {
+ result = true;
+ break;
+ }
+ }
+ }
+
+ visibleChildCache.put(element, result);
+ }
+ return visibleChildCache.get(element);
+ }
+
+ @Override
+ public TreePath findPath(Object semanticElement, Object[] rootElements) {
+ return TreePath.EMPTY; // TODO : Naive search
+ }
+
+ protected void clearCache() {
+ cache.clear();
+ visibleChildCache.clear();
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ clearCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The basic implementation is a naive tree search
+ *
+ * @param elementToReveal
+ */
+ @Override
+ public void revealSemanticElement(List<?> elementsToReveal) {
+ if (viewer != null) {
+ // FIXME: TreeViewers cannot do this search when the items have not yet be expanded.
+ // We need to search on the ContentProvider and pass a TreeSelection to the viewer
+ viewer.setSelection(new StructuredSelection(elementsToReveal), true);
+ }
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ this.viewer = viewer;
+ }
+
+ protected Viewer viewer;
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/StrategyBasedContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/StrategyBasedContentProvider.java
new file mode 100644
index 00000000000..c32540fa59e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/StrategyBasedContentProvider.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+
+public class StrategyBasedContentProvider extends EncapsulatedContentProvider {
+
+ protected TreeBrowseStrategy browseStrategy;
+
+ protected TreeBrowseStrategy revealStrategy;
+
+ protected StructuredViewer viewer;
+
+ public StrategyBasedContentProvider(TreeBrowseStrategy browseStrategy, TreeBrowseStrategy revealStrategy) {
+ setRevealStrategy(revealStrategy);
+ setBrowseStrategy(browseStrategy);
+ }
+
+ public void setBrowseStrategy(TreeBrowseStrategy strategy) {
+ if (strategy != null) {
+ browseStrategy = strategy;
+ encapsulated = browseStrategy;
+ }
+ }
+
+ public void setRevealStrategy(TreeBrowseStrategy strategy) {
+ if (strategy != null) {
+ revealStrategy = strategy;
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (browseStrategy != null) {
+ browseStrategy.dispose();
+ }
+ if (revealStrategy != null) {
+ revealStrategy.dispose();
+ }
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ if (viewer instanceof StructuredViewer) {
+ this.viewer = (StructuredViewer) viewer;
+ } else {
+ this.viewer = null;
+ }
+
+ revealStrategy.inputChanged(viewer, oldInput, newInput);
+ browseStrategy.inputChanged(viewer, oldInput, newInput);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Reveals and selects the given semantic elements
+ */
+ @Override
+ public void revealSemanticElement(List<?> semanticElementsList) {
+ revealStrategy.revealSemanticElement(semanticElementsList);
+ // List<Object> containerElements = new LinkedList<Object>();
+ //
+ // for(Object semanticElement : semanticElementsList) {
+ // TreePath path = revealStrategy.findPath(semanticElement, getElements(viewer.getInput()));
+ // if(path.getSegmentCount() > 0) {
+ // viewer.reveal(path);
+ // containerElements.add(path.getLastSegment());
+ // }
+ // }
+ //
+ // viewer.setSelection(new StructuredSelection(containerElements));
+ }
+
+ @Override
+ public TreeBrowseStrategy getBrowseStrategy() {
+ return browseStrategy;
+ }
+
+ @Override
+ public TreeBrowseStrategy getRevealStrategy() {
+ return revealStrategy;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/TreeBrowseStrategy.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/TreeBrowseStrategy.java
new file mode 100644
index 00000000000..5d66c6f5262
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/TreeBrowseStrategy.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement;
+
+
+/**
+ * An interface to define a strategy for browsing a Tree
+ *
+ * @author Camille Letavernier
+ */
+public interface TreeBrowseStrategy extends ITreeContentProvider, IRevealSemanticElement {
+
+ /**
+ * Finds a path to the given element
+ *
+ * @param element
+ * The semanticElement to find
+ * @parem input
+ * The root Elements
+ * @return
+ * @deprecated See {@link #revealSemanticElement(java.util.List)} instead
+ */
+ @Deprecated
+ public TreePath findPath(Object semanticElement, Object[] roots);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/WorkspaceRevealStrategy.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/WorkspaceRevealStrategy.java
new file mode 100644
index 00000000000..f08c5a76ddf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/strategy/WorkspaceRevealStrategy.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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.infra.widgets.strategy;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+
+/**
+ * A Strategy to search for a Resource in the Workspace
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class WorkspaceRevealStrategy extends ProviderBasedBrowseStrategy {
+
+ public WorkspaceRevealStrategy(ITreeContentProvider provider) {
+ super(provider);
+ }
+
+ public WorkspaceRevealStrategy() {
+ super();
+ }
+
+ @Override
+ public void revealSemanticElement(List<?> elementsToReveal) {
+ if (viewer instanceof TreeViewer) {
+ TreeViewer treeViewer = (TreeViewer) viewer;
+ TreePath[] paths = new TreePath[elementsToReveal.size()];
+ int i = 0;
+
+ List<?> roots = Arrays.asList(getElements());
+
+ for (Object elementToReveal : elementsToReveal) {
+ LinkedList<IResource> segments = new LinkedList<IResource>();
+
+ if (elementToReveal instanceof IResource) {
+ IResource currentElement = (IResource) elementToReveal;
+
+ segments.add(currentElement);
+
+ currentElement = currentElement.getParent();
+ while (currentElement != null) {
+ segments.addFirst(currentElement);
+
+ if (roots.contains(currentElement)) {
+ break; // If the tree root is not the Workspace Root, stop now
+ }
+ currentElement = currentElement.getParent();
+ }
+ }
+
+ paths[i++] = new TreePath(segments.toArray());
+ }
+
+ TreeSelection selection = new TreeSelection(paths);
+ treeViewer.setSelection(selection, true);
+ } else {
+ super.revealSemanticElement(elementsToReveal);
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/DoNothingCompletionProposal.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/DoNothingCompletionProposal.java
new file mode 100644
index 00000000000..b37f22846f5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/DoNothingCompletionProposal.java
@@ -0,0 +1,146 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * @author VL222926
+ *
+ */
+public class DoNothingCompletionProposal implements ICompletionProposal {
+ /** The string to be displayed in the completion proposal popup. */
+ private String fDisplayString;
+ /** The replacement string. */
+ private String fReplacementString;
+ /** The replacement offset. */
+ private int fReplacementOffset;
+ // /** The replacement length. */
+ private int fReplacementLength;
+ /** The cursor position after this proposal has been applied. */
+ private int fCursorPosition;
+ /** The image to be displayed in the completion proposal popup. */
+ private Image fImage;
+ /** The context information of this proposal. */
+ private IContextInformation fContextInformation;
+ /** The additional info of this proposal. */
+ private String fAdditionalProposalInfo;
+
+ /**
+ * Creates a new completion proposal based on the provided information. The replacement string is
+ * considered being the display string too. All remaining fields are set to <code>null</code>.
+ *
+ * @param replacementString
+ * the actual string to be inserted into the document
+ * @param replacementOffset
+ * the offset of the text to be replaced
+ * @param replacementLength
+ * the length of the text to be replaced
+ * @param cursorPosition
+ * the position of the cursor following the insert relative to replacementOffset
+ */
+ public DoNothingCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition) {
+ this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null);
+ }
+
+ /**
+ * Creates a new completion proposal. All fields are initialized based on the provided information.
+ *
+ * @param replacementString
+ * the actual string to be inserted into the document
+ * @param replacementOffset
+ * the offset of the text to be replaced
+ * @param replacementLength
+ * the length of the text to be replaced
+ * @param cursorPosition
+ * the position of the cursor following the insert relative to replacementOffset
+ * @param image
+ * the image to display for this proposal
+ * @param displayString
+ * the string to be displayed for the proposal
+ * @param contextInformation
+ * the context information associated with this proposal
+ * @param additionalProposalInfo
+ * the additional information associated with this proposal
+ */
+ public DoNothingCompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) {
+ Assert.isNotNull(replacementString);
+ Assert.isTrue(replacementOffset >= 0);
+ Assert.isTrue(replacementLength >= 0);
+ Assert.isTrue(cursorPosition >= 0);
+
+ fReplacementString = replacementString;
+ fReplacementOffset = replacementOffset;
+ fReplacementLength = replacementLength;
+ fCursorPosition = cursorPosition;
+ fImage = image;
+ fDisplayString = displayString;
+ fContextInformation = contextInformation;
+ fAdditionalProposalInfo = additionalProposalInfo;
+ }
+
+ /**
+ *
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
+ *
+ * @param document
+ */
+ public void apply(IDocument document) {
+ // nothing to do
+ }
+
+ /*
+ * @see ICompletionProposal#getSelection(IDocument)
+ */
+ public Point getSelection(IDocument document) {
+ return new Point(fReplacementOffset + fCursorPosition, 0);
+ }
+
+ /*
+ * @see ICompletionProposal#getContextInformation()
+ */
+ public IContextInformation getContextInformation() {
+ return fContextInformation;
+ }
+
+ /*
+ * @see ICompletionProposal#getImage()
+ */
+ public Image getImage() {
+ return fImage;
+
+ }
+
+ /*
+ * @see ICompletionProposal#getDisplayString()
+ */
+ public String getDisplayString() {
+ if (fDisplayString != null)
+ return fDisplayString;
+ return fReplacementString;
+ }
+
+ /*
+ * @see ICompletionProposal#getAdditionalProposalInfo()
+ */
+ public String getAdditionalProposalInfo() {
+ return fAdditionalProposalInfo;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/FileUtil.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/FileUtil.java
new file mode 100644
index 00000000000..13831478833
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/FileUtil.java
@@ -0,0 +1,112 @@
+/*****************************************************************************
+ * 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.infra.widgets.util;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.editors.StringFileSelector;
+
+/**
+ * A helper class for resolving files and path, either in the workspace or
+ * on the File system
+ *
+ * @author Camille Letavernier
+ * @see StringFileSelector
+ */
+public class FileUtil {
+
+ /**
+ * Returns the path to the IFile. If absolute is true, returns the path
+ * from the FileSystem. Otherwise, returns the path from the workspace.
+ *
+ * @param file
+ * @param absolute
+ * @return
+ */
+ public static String getPath(IFile file, boolean absolute) {
+ if (absolute) {
+ return file.getLocation().toString();
+ }
+ return file.getFullPath().toString();
+ }
+
+ /**
+ * Returns the IFile (Workspace file) from the given location.
+ * The location may be either absolute (From the FileSystem) or
+ * relative to the workspace root.
+ *
+ * @param location
+ * @return
+ */
+ public static IFile getIFile(String location) {
+ // Search the file in the workspace
+ IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();
+ IPath path = new Path(location);
+ IFile currentFile = null;
+ try {
+ currentFile = workspace.getFile(path);
+ } catch (IllegalArgumentException ex) {
+ // Ignore
+ }
+
+ // Then search it on the disk
+ if (currentFile == null || !currentFile.exists()) {
+ currentFile = workspace.getFileForLocation(path);
+ }
+
+ return currentFile;
+ }
+
+ /**
+ * Returns the Java File from the given location.
+ * The location may be either absolute (From the FileSystem) or
+ * relative to the workspace root.
+ *
+ * @param location
+ * @return
+ */
+ public static File getFile(String location) {
+ IFile iFile = getIFile(location);
+ if (iFile == null || !iFile.exists()) {
+ return new File(location);
+ }
+
+ return new File(iFile.getLocationURI());
+ }
+
+ /**
+ * Returns the Java File from the given location.
+ * The location is relative to the workspace root.
+ *
+ * @param location
+ * @return
+ */
+ public static File getWorkspaceFile(String location) {
+ IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();
+ IPath path = new Path(location);
+ IFile currentFile = null;
+ try {
+ currentFile = workspace.getFile(path);
+ } catch (IllegalArgumentException ex) {
+ Activator.log.error(ex);
+ return null;
+ }
+
+ return currentFile.getLocation().toFile();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/INameResolutionHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/INameResolutionHelper.java
new file mode 100644
index 00000000000..727c9c6b46e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/INameResolutionHelper.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.List;
+
+/**
+ * Common interface to use to find elements from a given string
+ *
+ */
+public interface INameResolutionHelper {
+
+ /**
+ *
+ * @param aString
+ * a string
+ * @return
+ * all elements whose the name starts with this string, or all found element if the string is <code>null</code> or empty
+ */
+ public List<?> getMatchingElements(final String aString);
+
+ /**
+ *
+ * @param aString
+ * a string
+ * @return
+ * all elements which have the wanted string as (qualified) name
+ */
+ public List<?> getElementsByName(final String aString);
+
+
+ /**
+ * @param namedElement
+ * @return
+ * the shortest qualified to use for the element
+ */
+ public List<String> getShortestQualifiedNames(Object element);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IPapyrusConverter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IPapyrusConverter.java
new file mode 100644
index 00000000000..0d24d7b1d9b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IPapyrusConverter.java
@@ -0,0 +1,164 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+
+/**
+ * @author VL222926
+ *
+ * This class provides method to convert Object to a string to edit or a string to display and vice-versa from a string to edit or to display to the real object
+ *
+ */
+public interface IPapyrusConverter extends INameResolutionHelper {
+
+ // the previous regex,which did not allow to get 'Class, when the user asked for the completion and
+ // PLEASE DO NOT ERASE THIS COMMENT
+ // public static final String FIND_PART_NAME_REGEX = "([^'\\x2C]+)|('[^']+')"; //$NON-NLS-1$
+
+ /**
+ * regex used to parse string on , and ',':
+ */
+ public static final String FIND_PART_NAME_REGEX = "([^'\\x2C]+)|('[^']+')|('(([^']*[\\x2C][^']*)))"; //$NON-NLS-1$
+
+ /**
+ * the string delimiter
+ */
+ public static final String STRING_DELIMITER = "\'"; //$NON-NLS-1$
+
+ /**
+ * the string separator for multivalued properties
+ */
+ public static final String STRING_SEPARATOR = ","; //$NON-NLS-1$
+
+ /**
+ * the string used for <code>null</code> value
+ */
+ public static final String UNDEFINED_VALUE = "<Undefined>";//$NON-NLS-1$
+
+ /**
+ * add this string to the suggestions when there are more than {@link #MAX_ELEMENTS_TO_DISPLAY}
+ */
+ public static final String MORE_ELEMENTS = "...";//$NON-NLS-1$
+
+ /**
+ * empty string
+ */
+ public static final String EMPTY_STRING = "";//$NON-NLS-1$
+
+ /**
+ *
+ * @param multiValueAsString
+ * the full String write in the StyledText
+ * @return
+ * a map with the name of the elements as value and the start and the end index of the name in the typed text as key
+ */
+ public Map<List<Integer>, String> getSubStringsWithTheirPositions(String multiValueAsString);
+
+ /**
+ *
+ * @param multiValueAsString
+ * a string
+ * @return
+ * all substring according to the applied regex
+ */
+ public List<String> splitFullStringToSubElementString(String multiValueAsString);
+
+ /**
+ *
+ * @param aString
+ * a string
+ * @return
+ * a istatus indicating if the string is valid or not
+ */
+ public IStatus isValidEditString(String aString);
+
+ /**
+ * Returns the parser's content assist processor
+ *
+ * @param element
+ * the element
+ * @return the content assist processor
+ */
+ public IContentAssistProcessor getCompletionProcessor(IAdaptable element);
+
+
+ /**
+ *
+ * @param object
+ * an object
+ * @param flag
+ * a flag which could be used for for the name qualification for example
+ * @return
+ * the string to display (label) representing the object
+ */
+ public String canonicalToDisplayValue(Object object, int flag);
+
+ /**
+ *
+ * @param object
+ * an object
+ * @param flag
+ * a flag which could be used for for the name qualification for example
+ * @return
+ * the string to edit (label) representing the object
+ */
+ public String canonicalToEditValue(Object object, int flag);
+
+ /**
+ *
+ * @param string
+ * a display string
+ * @param flag
+ * a flag which could be used for for the name qualification for example
+ * @return
+ * the object represented by the displayed string
+ */
+ public Object displayToCanonicalValue(String string, int flag);
+
+ /**
+ *
+ * @param string
+ * an edited string
+ * @param flag
+ * a flag which could be used for for the name qualification for example
+ * @return
+ * the object represented by the edited string
+ */
+ public Object editToCanonicalValue(String string, int flag);
+
+ /**
+ *
+ * @param string
+ * an edited string
+ * @return
+ * the the equivalent string to use for edition
+ */
+ public String editToDisplayValue(String string);
+
+ /**
+ *
+ * @param string
+ * a displayed string
+ * @return
+ * the the equivalent string to use for
+ */
+ public String displayToEditValue(String string);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IRevealSemanticElement.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IRevealSemanticElement.java
new file mode 100644
index 00000000000..9b42bdd5de5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/IRevealSemanticElement.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * 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:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ */
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.List;
+
+/**
+ * this interface is used to reveal element that are given in parameter. Example
+ * of the use case: the class that implements this interface can be a diagram
+ * that select all editparts that are linked to the given list of semantic
+ * element
+ *
+ */
+public interface IRevealSemanticElement {
+
+ /**
+ * reveal all elements that represent an element in the given list.
+ *
+ * @param elementList
+ * list of semantic element that we want to reveal, <B> cannot be
+ * null</B>
+ */
+ public void revealSemanticElement(List<?> elementList);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetNameResolutionHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetNameResolutionHelper.java
new file mode 100644
index 00000000000..104bfabd7df
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetNameResolutionHelper.java
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+import org.eclipse.papyrus.infra.widgets.util.INameResolutionHelper;
+
+/**
+ * Interface used to declare a ISNameResolutionHelper
+ *
+ */
+public interface ISetNameResolutionHelper {
+
+ /**
+ *
+ * @param helper
+ * a name resolution helper
+ */
+ public void setNameResolutionHelper(INameResolutionHelper helper);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetPapyrusConverter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetPapyrusConverter.java
new file mode 100644
index 00000000000..4da7e5a75eb
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ISetPapyrusConverter.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+/**
+ * @author Vincent Lorenzo
+ *
+ */
+public interface ISetPapyrusConverter {
+
+ /**
+ *
+ * @param converter
+ * the papyrus converter to use
+ */
+ public void setPapyrusConverter(IPapyrusConverter converter);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageConstants.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageConstants.java
new file mode 100644
index 00000000000..742698a5a4d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageConstants.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+/**
+ * @author VL222926
+ *
+ */
+public class ImageConstants {
+
+ /**
+ * Constructor.
+ *
+ */
+ private ImageConstants() {
+ // to prevent instanciation
+ }
+
+ /**
+ * the local path to get the papyrus icon
+ */
+ public static final String PAPYRUS_ICON_PATH = "/icons/papyrus.png"; //$NON-NLS-1$
+
+ /**
+ * the local path to get the edit icon in 12x12
+ */
+ public static final String EDIT_12_12_ICON_PATH = "/icons/Edit_12x12.gif";//$NON-NLS-1$
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageDescriptorManager.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageDescriptorManager.java
new file mode 100644
index 00000000000..31c5cfbc3e5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ImageDescriptorManager.java
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Manager for ImageDescriptor by keys
+ */
+public class ImageDescriptorManager {
+
+ protected Map<ImageDescriptor, String> imageDescriptor2Key = new HashMap<ImageDescriptor, String>();
+
+ protected int value;
+
+ public void reset() {
+ imageDescriptor2Key.clear();
+ }
+
+ public String getKey(ImageDescriptor descriptor) {
+ String key = null;
+ if (!imageDescriptor2Key.containsKey(descriptor)) {
+ key = computeKey(descriptor);
+ imageDescriptor2Key.put(descriptor, key);
+ } else {
+ key = imageDescriptor2Key.get(descriptor);
+ }
+ return key;
+ }
+
+ protected String computeKey(ImageDescriptor descriptor) {
+ return "" + descriptor.hashCode();
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/MultiplicityConstants.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/MultiplicityConstants.java
new file mode 100644
index 00000000000..69b6372375d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/MultiplicityConstants.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.util;
+
+/**
+ * The multiplicity constants.
+ */
+public interface MultiplicityConstants {
+
+ /**
+ * The multiplicity editor preference identifier.
+ */
+ public static final String MULTIPLICITY_EDITOR_MODE = "multiplicityEditorMode"; //$NON-NLS-1$
+
+ /**
+ * The simple mode preference identifier.
+ */
+ public static final String SIMPLE_MODE = "simpleMode"; //$NON-NLS-1$
+
+ /**
+ * The simple mode text value display.
+ */
+ public static final String SIMPLE_MODE_TEXT_VALUE = "Simple mode"; //$NON-NLS-1$
+
+ /**
+ * The advanced mode preference identifier.
+ */
+ public static final String ADVANCED_MODE = "advanceMode"; //$NON-NLS-1$
+
+ /**
+ * The advanced mode text value display.
+ */
+ public static final String ADVANCED_MODE_TEXT_VALUE = "Advanced mode"; //$NON-NLS-1$
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/NavigationTarget.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/NavigationTarget.java
new file mode 100644
index 00000000000..4cf5461ddf0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/NavigationTarget.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.Collection;
+
+/**
+ * This interface is used to select and reveal element that are given in parameter. Example
+ * of the use case: the class that implements this interface can be a diagram
+ * that select all editparts that are linked to the given list of elements.
+ *
+ * The element parameter can be either a semantic element (Which will likely be wrapped
+ * in a graphical element such as an EditPart), or a notation element (Such as a GMF notation::View)
+ */
+public interface NavigationTarget {
+
+ /**
+ * Select and reveal the given element. Element may be either a semantic element (e.g. a uml::Class)
+ * or a graphical element (e.g. GMF notation::View)
+ *
+ * @param element
+ * @return
+ * True if the element has been selected, false otherwise
+ */
+ public boolean revealElement(Object element);
+
+ /**
+ * Select and reveal the given elements. Elements may be either semantic elements (e.g. uml::Class)
+ * or graphical elements (e.g. GMF notation::View)
+ *
+ * @param elements
+ * @return
+ * True if the elements have been selected, false otherwise
+ */
+ public boolean revealElement(Collection<?> elements);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/PopupButtonMenu.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/PopupButtonMenu.java
new file mode 100644
index 00000000000..78ea06876d4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/PopupButtonMenu.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.util;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Menu;
+
+
+/**
+ * A pop-up menu to attach to buttons, which presents a flat menu of actions for the user to choose from.
+ */
+public class PopupButtonMenu {
+
+ private final Button button;
+
+ private MenuManager menu;
+
+
+ /**
+ * Initializes me with a button on which to present the pop-up menu.
+ *
+ * @param button
+ * the button on which I attach a pop-up menu
+ */
+ public PopupButtonMenu(Button button) {
+ this.button = button;
+
+ initialize();
+ }
+
+ /**
+ * Add an action to the drop-down menu. Note that this explicitly excludes nested menu structures.
+ *
+ * @param action
+ * an action to add to the menu
+ */
+ public void addAction(IAction action) {
+ menu.add(action);
+ }
+
+ private void initialize() {
+ menu = new MenuManager();
+
+ button.addDisposeListener(new DisposeListener() {
+
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ if (menu != null) {
+ menu.dispose();
+ menu = null;
+ }
+ }
+ });
+
+ button.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ showMenu(e.x, e.y);
+ }
+ });
+ }
+
+ private void showMenu(int x, int y) {
+ if (menu != null) {
+ Menu menu = this.menu.createContextMenu(button);
+ // don't set the menu as the button's context menu! We don't want right-click to show it
+
+ menu.setLocation(button.toDisplay(x, y));
+ menu.setVisible(true);
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealResultCommand.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealResultCommand.java
new file mode 100644
index 00000000000..eb020577ef4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealResultCommand.java
@@ -0,0 +1,220 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST, Christian W. Damus, 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:
+ * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.fr - Initial API and implementation
+ * Christian W. Damus - bug 436954
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandWrapper;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+
+/**
+ * Wrapper to reveal the results (using with reveal semantic protocol) after a command in View.
+ *
+ * @author Gabriel Pascual
+ */
+public class RevealResultCommand extends CommandWrapper {
+
+ /** The view part. */
+ private IViewPart viewPart = null;
+
+ /** The source object. */
+ private Object sourceObject = null;
+
+ /** The reveal all results. */
+ private boolean revealAllResults = false;
+
+ /**
+ * Constructor.
+ *
+ * @param command
+ */
+ public RevealResultCommand(Command command, IViewPart part, Object editObject) {
+ super(command);
+ viewPart = part;
+ sourceObject = editObject;
+ }
+
+ /**
+ * Sets the reveal all results.
+ *
+ * @param revealAllResults
+ * the revealAllResults to set
+ */
+ private void setRevealAllResults(boolean revealAllResults) {
+ this.revealAllResults = revealAllResults;
+ }
+
+ /**
+ * Wrap.
+ *
+ * @param command
+ * the command
+ * @param part
+ * the part
+ * @param container
+ * the container
+ * @param revealAllResults
+ * the reveal all results
+ * @return the command
+ */
+ public static Command wrap(Command command, IViewPart part, EObject container, boolean revealAllResults) {
+ RevealResultCommand wrappedCommand = new RevealResultCommand(command, part, container);
+ wrappedCommand.setRevealAllResults(revealAllResults);
+ return wrappedCommand;
+ }
+
+ /**
+ * Wrap.
+ *
+ * @param command
+ * the command
+ * @param part
+ * the part
+ * @param container
+ * the container
+ * @return the command
+ */
+ public static Command wrap(Command command, IViewPart part, EObject container) {
+ return new RevealResultCommand(command, part, container);
+ }
+
+ /**
+ * Wrap.
+ *
+ * @param command
+ * the command
+ * @param part
+ * the part
+ * @return the command
+ */
+ public static Command wrap(Command command, IViewPart part) {
+ return wrap(command, part, null);
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.CommandWrapper#execute()
+ *
+ */
+ @Override
+ public void execute() {
+
+ super.execute();
+ selectResult();
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.CommandWrapper#undo()
+ *
+ */
+ @Override
+ public void undo() {
+ super.undo();
+ selectSource();
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.CommandWrapper#redo()
+ *
+ */
+ @Override
+ public void redo() {
+ super.redo();
+ selectResult();
+ }
+
+ /**
+ * Reveal target.
+ *
+ * @param target
+ * the target
+ */
+ private void revealTarget(final List<?> target) {
+ Display.getCurrent().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+
+ if (viewPart instanceof IRevealSemanticElement) {
+ ((IRevealSemanticElement) viewPart).revealSemanticElement(target);
+
+ }
+
+ }
+ });
+ }
+
+ /**
+ * Select command result.
+ */
+ private void selectResult() {
+ Collection<?> results = getResultsCommand();
+ if (!results.isEmpty()) {
+ if (revealAllResults) {
+ revealTarget(Arrays.asList(results.toArray()));
+
+ } else {
+
+
+ Iterator<?> resultIterator = results.iterator();
+
+ // Get first result
+ final Object result = resultIterator.next();
+ revealTarget(Arrays.asList(new Object[] { result }));
+ }
+
+ }
+ }
+
+ /**
+ * Gets the results command.
+ *
+ * @return the results command
+ */
+ private Collection<?> getResultsCommand() {
+
+ // Get results list
+ Collection<?> resultsCommand = getResult();
+ if (getResult().isEmpty()) {
+
+ // Get affected objects list if it is not a command with result
+ resultsCommand = getAffectedObjects();
+ }
+
+ return resultsCommand;
+ }
+
+ /**
+ * Select source.
+ */
+ private void selectSource() {
+
+ if (sourceObject != null) {
+ revealTarget(Arrays.asList(new Object[] { sourceObject }));
+
+ } else if (!getAffectedObjects().isEmpty()) {
+
+ // Try with the affected objects
+ revealTarget(Arrays.asList(getAffectedObjects().toArray()));
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealSemanticElementWrapper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealSemanticElementWrapper.java
new file mode 100644
index 00000000000..855ff9f5661
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/RevealSemanticElementWrapper.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+
+/**
+ * A wrapper to convert a IRevealSemanticElement to an INavigationTarget
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class RevealSemanticElementWrapper implements NavigationTarget {
+
+ private final IRevealSemanticElement revealSemanticElement;
+
+ public RevealSemanticElementWrapper(IRevealSemanticElement revealSemanticElement) {
+ this.revealSemanticElement = revealSemanticElement;
+ }
+
+ @Override
+ public boolean revealElement(Object element) {
+ return revealElement(Collections.singletonList(element));
+ }
+
+ @Override
+ public boolean revealElement(Collection<?> elements) {
+ revealSemanticElement.revealSemanticElement(new LinkedList<Object>(elements));
+ return false;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ValueUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ValueUtils.java
new file mode 100644
index 00000000000..208d533a677
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/util/ValueUtils.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.util;
+
+/**
+ * @author VL222926
+ *
+ */
+public class ValueUtils {
+
+ /**
+ * Constructor.
+ *
+ */
+ private ValueUtils() {
+ // to prevent instanciation
+ }
+
+ /**
+ * value used to identify feature with multiplicity to *
+ */
+ public static final int MANY = -1;
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/AbstractValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/AbstractValidator.java
new file mode 100644
index 00000000000..d21390be40d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/AbstractValidator.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.widgets.Activator;
+
+/**
+ * An abstract implementation of the IValidator interface
+ *
+ * @author Camille Letavernier
+ *
+ */
+public abstract class AbstractValidator implements IValidator {
+
+ protected String pluginId;
+
+ public void setPluginID(String pluginId) {
+ this.pluginId = pluginId;
+ }
+
+ protected IStatus error(String message) {
+ return new Status(IStatus.ERROR, getPluginId(), message);
+ }
+
+ public String getPluginId() {
+ if (pluginId == null) {
+ return Activator.PLUGIN_ID;
+ } else {
+ return pluginId;
+ }
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanInputValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanInputValidator.java
new file mode 100644
index 00000000000..d1354a53d3d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanInputValidator.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+
+/**
+ * InputValidator for boolean
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class BooleanInputValidator extends InputValidatorWrapper {
+
+ public BooleanInputValidator() {
+ super(new BooleanValidator());
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanValidator.java
new file mode 100644
index 00000000000..26ef894a65c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/BooleanValidator.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Modification to match IValidator
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.tools.util.BooleanHelper;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+/**
+ * InputValidator for boolean
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class BooleanValidator extends AbstractValidator {
+
+
+ /**
+ *
+ * @param newValue
+ * @return {@link Status#OK_STATUS} if the newValue is valid and {@link IStatus#ERROR} when newValue is
+ * invalid
+ */
+ @Override
+ public IStatus validate(Object newValue) {
+ if (newValue instanceof Boolean) {
+ return Status.OK_STATUS;
+ }
+
+ if (newValue instanceof String && BooleanHelper.isBoolean((String) newValue)) {
+ return Status.OK_STATUS;
+ }
+
+ return error(Messages.BooleanInputValidator_NotABoolean);
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/InputValidatorWrapper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/InputValidatorWrapper.java
new file mode 100644
index 00000000000..0a23bbde936
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/InputValidatorWrapper.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IInputValidator;
+
+/**
+ * A Wrapper for IValidator to IInputValidator
+ *
+ * @author Camille Letavernier
+ */
+public class InputValidatorWrapper implements IInputValidator {
+
+ protected IValidator validator;
+
+ public InputValidatorWrapper(IValidator validator) {
+ Assert.isNotNull(validator);
+ this.validator = validator;
+ }
+
+ @Override
+ public String isValid(String newText) {
+ IStatus status = validator.validate(newText);
+ if (status.isOK()) {
+ return null;
+ }
+
+ return status.getMessage();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerInputValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerInputValidator.java
new file mode 100644
index 00000000000..2292a1f00a6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerInputValidator.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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 (camille.letavernier@cea.fr) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+
+
+/**
+ * Validator for Integer
+ *
+ */
+public class IntegerInputValidator extends InputValidatorWrapper {
+
+
+ public IntegerInputValidator() {
+ super(new IntegerValidator());
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerValidator.java
new file mode 100644
index 00000000000..aedb919bea9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/IntegerValidator.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Modification to match IValidator
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+/**
+ * InputValidator for Integer
+ *
+ * @author Vincent Lorenzo
+ *
+ */
+public class IntegerValidator extends AbstractValidator {
+
+
+ /**
+ *
+ * @param newValue
+ * @return {@link Status#OK_STATUS} if the newValue is valid and {@link IStatus#ERROR} when newValue is
+ * invalid
+ */
+ @Override
+ public IStatus validate(Object newValue) {
+ if (newValue instanceof Integer) {
+ return Status.OK_STATUS;
+ }
+
+ if (newValue instanceof String) {
+ try {
+ Integer.parseInt((String) newValue);
+ return Status.OK_STATUS;
+ } catch (NumberFormatException ex) {
+ return error(Messages.IntegerInputValidator_NotAnIntegerMessage);
+ }
+ }
+
+ return error(Messages.IntegerInputValidator_NotAnIntegerMessage);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealInputValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealInputValidator.java
new file mode 100644
index 00000000000..db187dfbd6d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealInputValidator.java
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+
+/**
+ * Validator for the Real
+ */
+public class RealInputValidator extends InputValidatorWrapper {
+
+ public RealInputValidator() {
+ super(new RealValidator());
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealValidator.java
new file mode 100644
index 00000000000..eda02e90576
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/RealValidator.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Modification to match IValidator
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+/**
+ * Validator for the Real
+ */
+public class RealValidator extends AbstractValidator {
+
+
+ /**
+ *
+ * @param newValue
+ * @return {@link Status#OK_STATUS} if the newValue is valid and {@link IStatus#ERROR} when newValue is
+ * invalid
+ */
+ @Override
+ public IStatus validate(Object newValue) {
+ if (newValue instanceof Double) {
+ return Status.OK_STATUS;
+ }
+
+ if (newValue instanceof String) {
+ try {
+ Double.parseDouble((String) newValue);
+ return Status.OK_STATUS;
+ } catch (NumberFormatException ex) {
+ return error(Messages.RealInputValidator_NotaRealMessage);
+ }
+ }
+
+ return error(Messages.RealInputValidator_NotaRealMessage);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalInputValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalInputValidator.java
new file mode 100644
index 00000000000..0d25097e25e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalInputValidator.java
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+
+/**
+ * Validator for the UnlimitedNaturalEditor. It accepts "-1", "*" and all integer >=0
+ */
+public class UnlimitedNaturalInputValidator extends InputValidatorWrapper {
+
+ public UnlimitedNaturalInputValidator() {
+ super(new UnlimitedNaturalValidator());
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalValidator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalValidator.java
new file mode 100644
index 00000000000..1b62638959f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/validator/UnlimitedNaturalValidator.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Modification to match IValidator
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.validator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+
+/**
+ * Validator for the UnlimitedNaturalEditor. It accepts "-1", "*" and all integer >=0
+ */
+public class UnlimitedNaturalValidator extends AbstractValidator {
+
+
+ public static final String INFINITE_STAR = "*"; //$NON-NLS-1$
+
+ public static final String INFINITE_MINUS_ONE = "-1"; //$NON-NLS-1$
+
+
+ /**
+ * @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
+ *
+ * @param newText
+ * @return <code>null</code> if the newText is valid an error message when newText is
+ * invalid
+ */
+ public String isValid(String newText) {
+ if (INFINITE_STAR.equals(newText) || INFINITE_MINUS_ONE.equals(newText)) {
+ return null;
+ }
+ boolean isValid = true;
+ try {
+ Integer myUnlimitedNatural = Integer.valueOf(newText);
+ if (myUnlimitedNatural < -1) {
+ isValid = false;
+ }
+ } catch (NumberFormatException e) {
+ isValid = false;
+ }
+
+ if (!isValid) {
+ return Messages.UnlimitedNaturalInputValidator_NotAnUnlimitedNaturalMessage;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param newValue
+ * @return {@link Status#OK_STATUS} if the newValue is valid and {@link IStatus#ERROR} when newValue is
+ * invalid
+ */
+ @Override
+ public IStatus validate(Object newValue) {
+ if (newValue instanceof Integer) {
+ int value = (Integer) newValue;
+ if (value == -1 || value >= 0) {
+ return Status.OK_STATUS;
+ }
+ }
+
+ if (newValue instanceof String) {
+ String newText = (String) newValue;
+
+ if (INFINITE_STAR.equals(newText) || INFINITE_MINUS_ONE.equals(newText)) {
+ return Status.OK_STATUS;
+ }
+
+ boolean isValid = true;
+ try {
+ Integer myUnlimitedNatural = Integer.parseInt(newText);
+ if (myUnlimitedNatural < -1) {
+ isValid = false;
+ }
+ } catch (NumberFormatException e) {
+ isValid = false;
+ }
+
+ if (isValid) {
+ return Status.OK_STATUS;
+ }
+ }
+
+ return error(Messages.UnlimitedNaturalInputValidator_NotAnUnlimitedNaturalMessage);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueEditAndSelectionWidget.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueEditAndSelectionWidget.java
new file mode 100644
index 00000000000..7d91e2d5e21
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueEditAndSelectionWidget.java
@@ -0,0 +1,168 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.widgets;
+
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.util.ImageConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author VL222926
+ *
+ */
+public class MultipleValueEditAndSelectionWidget extends MultipleValueSelectionWidget {
+
+ /**
+ * if <code>true</code> the edition button will be displayed
+ */
+ private boolean allowEdition;
+
+
+ /**
+ * The edit action button
+ */
+ protected Button edit;
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ */
+ public MultipleValueEditAndSelectionWidget(IElementSelector selector) {
+ super(selector);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ */
+ public MultipleValueEditAndSelectionWidget(IElementSelector selector, boolean unique) {
+ super(selector, unique);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ */
+ public MultipleValueEditAndSelectionWidget(IElementSelector selector, boolean unique, boolean ordered) {
+ super(selector, unique, ordered);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ * @param upperBound
+ */
+ public MultipleValueEditAndSelectionWidget(IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ super(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#init()
+ *
+ */
+ @Override
+ protected void init() {
+ super.init();
+ // please, keep the default value to false
+ this.allowEdition = false;
+ }
+
+ /**
+ * @return the allowEdition
+ */
+ public boolean isAllowEdition() {
+ return allowEdition;
+ }
+
+ /**
+ * @param allowEdition
+ * the allowEdition to set
+ */
+ public void setAllowEdition(boolean allowEdition) {
+ this.allowEdition = allowEdition;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#createRightButtonsSection(org.eclipse.swt.widgets.Composite)
+ *
+ * @param parent
+ */
+ @Override
+ protected void createRightButtonsSection(Composite parent) {
+ super.createRightButtonsSection(parent);
+ if (isAllowEdition()) {
+ this.edit = new Button(rightButtonsSection, SWT.PUSH);
+ edit.setImage(Activator.getDefault().getImage(ImageConstants.EDIT_12_12_ICON_PATH)); //$NON-NLS-1$
+ edit.addSelectionListener(this);
+ edit.setToolTipText(Messages.MultipleValueEditAndSelectionWidget_EditSelectedElement);
+ }
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#updateControls()
+ *
+ */
+ @Override
+ public void updateControls() {
+ super.updateControls();
+ if(allowEdition){
+ updateControl(edit, this.factory!=null && this.factory.canEdit());
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (edit != null && e.widget == edit) {
+ edit();
+ this.selectedElementsViewer.refresh();
+ }
+ super.widgetSelected(e);
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the selected element can be edited
+ */
+ protected boolean canEdit() {
+ return allowEdition && this.factory.canEdit();
+ }
+
+ /**
+ * edit the selected element
+ */
+ protected void edit() {
+ // nothing to do here
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWidget.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWidget.java
new file mode 100644
index 00000000000..eecf456c52a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWidget.java
@@ -0,0 +1,822 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Adapted code from Camille Letavernier (CEA LIST) in MultipleValueSelectorDialog
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.widgets;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelectionListener;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider;
+import org.eclipse.papyrus.infra.widgets.util.ValueUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+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.Tree;
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * @author VL222926
+ * Class extracted from MultipleValueSelectorDialog
+ *
+ */
+public class MultipleValueSelectionWidget implements ISelectionChangedListener, IDoubleClickListener, IElementSelectionListener, SelectionListener, IDisposable {
+
+ /**
+ * The object selector
+ */
+ protected IElementSelector selector;
+
+ /**
+ * The SWT Composite in which the selector is drawn
+ */
+ protected Composite selectorSection;
+
+ /**
+ * The add/remove/addAll buttons section
+ */
+ protected Composite buttonsSection;
+
+ /**
+ * The up/down buttons section
+ */
+ protected Composite rightButtonsSection;
+
+ /**
+ * The listViewer for chosen elements
+ */
+ protected TreeViewer selectedElementsViewer;
+
+ /**
+ * The list for chosen elements
+ */
+ protected Tree selectedElements;
+
+ /**
+ * The add action button
+ */
+ protected Button add;
+
+ /**
+ * The create action button
+ */
+ protected Button create;
+
+ /**
+ * The delete action button
+ */
+ protected Button delete;
+
+ /**
+ * The remove action button
+ */
+ protected Button remove;
+
+ /**
+ * The add all action button
+ */
+ protected Button addAll;
+
+ /**
+ * The remove all action button
+ */
+ protected Button removeAll;
+
+ /**
+ * the up action button
+ */
+ protected Button up;
+
+ /**
+ * the down action button
+ */
+ protected Button down;
+
+ /**
+ * The label provider for the listViewer of chosen elements
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The currently chosen elements
+ */
+ protected final Collection<Object> allElements;
+
+ /**
+ * Indicates if the values should be unique (according to Object.equals())
+ */
+ protected boolean unique;
+
+ /**
+ * Indicates if the list is ordered
+ */
+ protected boolean ordered;
+
+ /**
+ * The factory for creating new elements
+ */
+ protected ReferenceValueFactory factory;
+
+ /**
+ * The model element being edited (if any), to which elements are to be added or removed.
+ */
+ protected Object contextElement;
+
+ /**
+ * The list of newly created objects
+ */
+ protected Set<Object> newObjects = new HashSet<Object>();
+
+
+ /**
+ * The maximum number of values selected.
+ */
+ protected int upperBound;
+
+ /**
+ * the initial selection
+ */
+ protected List<?> initialSelection;
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * The element selector used by this dialog
+ */
+ public MultipleValueSelectionWidget(IElementSelector selector) {
+ this(selector, false, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectionWidget(IElementSelector selector, boolean unique) {
+ this(selector, unique, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueSelectionWidget(IElementSelector selector, boolean unique, boolean ordered) {
+ this(selector, unique, false, ValueUtils.MANY);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ * @param upperBound
+ * The maximum number of values selected.
+ */
+ public MultipleValueSelectionWidget(IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ Assert.isNotNull(selector, "The element selector should be defined"); //$NON-NLS-1$
+ this.selector = selector;
+ allElements = unique ? new LinkedHashSet<Object>() : new LinkedList<Object>();
+ this.unique = unique;
+ this.ordered = ordered;
+ this.upperBound = upperBound;
+ selector.addElementSelectionListener(this);
+ init();
+ }
+
+ /**
+ * initialize the widget if required
+ */
+ protected void init() {
+ // nothing to do
+ }
+
+ /**
+ * Create the contents of the dialog
+ *
+ * @return
+ * the the composite which encapsulate all the sub composite
+ */
+ public final Composite create(Composite composite) {
+ Composite parent = createContents(composite);
+ updateControls();
+ return parent;
+ }
+
+ /**
+ * Create the contents of the dialog
+ *
+ * @return
+ * the the composite which encapsulate all the sub composite
+ */
+ protected Composite createContents(Composite parent) {
+ Object parentLayout = parent.getLayout();
+ GridLayout layout = null;
+ if (parentLayout instanceof GridLayout) {
+ layout = (GridLayout) parentLayout;
+ } else {
+ parent = new Composite(parent, SWT.NONE);
+ layout = new GridLayout();
+ parent.setLayout(layout);
+ }
+
+ layout.numColumns = 2;
+ layout.makeColumnsEqualWidth = true;
+
+ Composite selectorPane = new Composite(parent, SWT.NONE);
+ selectorPane.setLayout(new GridLayout(2, false));
+ selectorPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Composite selectedPane = new Composite(parent, SWT.NONE);
+ selectedPane.setLayout(new GridLayout(2, false));
+ selectedPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ createSelectorSection(selectorPane);
+ createControlsSection(selectorPane);
+ createListSection(selectedPane);
+ createRightButtonsSection(selectedPane);
+
+ allElements.clear();
+ allElements.addAll(getInitialElementSelections());
+ return parent;
+ }
+
+
+
+
+ public void setInitialSelections(List<?> selectedElements) {
+ this.initialSelection = selectedElements;
+ allElements.clear();
+ allElements.addAll(getInitialElementSelections());
+ }
+
+ /**
+ * @return
+ */
+ private Collection<? extends Object> getInitialElementSelections() {
+ if (this.initialSelection == null) {
+ return Collections.emptyList();
+ }
+ return this.initialSelection;
+ }
+
+ /**
+ * Creates the selector section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createSelectorSection(Composite parent) {
+ selectorSection = new Composite(parent, SWT.NONE);
+ selectorSection.setLayout(new FillLayout());
+ selectorSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ selector.createControls(selectorSection);
+ }
+
+ /**
+ * Creates the main controls section (Add, remove, Add all, remove all)
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createControlsSection(Composite parent) {
+ buttonsSection = new Composite(parent, SWT.NONE);
+ buttonsSection.setLayout(new GridLayout(1, true));
+
+ add = new Button(buttonsSection, SWT.PUSH);
+ add.setImage(Activator.getDefault().getImage("/icons/arrow_right.gif")); //$NON-NLS-1$
+ add.addSelectionListener(this);
+ add.setToolTipText(Messages.MultipleValueSelectorDialog_AddSelectedElements);
+
+ remove = new Button(buttonsSection, SWT.PUSH);
+ remove.setImage(Activator.getDefault().getImage("/icons/arrow_left.gif")); //$NON-NLS-1$
+ remove.addSelectionListener(this);
+ remove.setToolTipText(Messages.MultipleValueEditor_RemoveSelectedElements);
+
+ addAll = new Button(buttonsSection, SWT.PUSH);
+ addAll.setImage(Activator.getDefault().getImage("/icons/arrow_double.gif")); //$NON-NLS-1$
+ addAll.addSelectionListener(this);
+ addAll.setToolTipText(Messages.MultipleValueSelectorDialog_AddAllElements);
+
+ /* Disable the bouton 'addAll' if currently chosen elements is greater than the maximum number of values selected */
+ if (this.upperBound != ValueUtils.MANY && allElements.size() > this.upperBound) {
+ addAll.setEnabled(false);
+ }
+
+
+ removeAll = new Button(buttonsSection, SWT.PUSH);
+ removeAll.setImage(Activator.getDefault().getImage("/icons/arrow_left_double.gif")); //$NON-NLS-1$
+ removeAll.addSelectionListener(this);
+ removeAll.setToolTipText(Messages.MultipleValueSelectorDialog_RemoveAllElements);
+ }
+
+ /**
+ * Creates the list displaying the currently selected elements
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ private void createListSection(Composite parent) {
+
+ selectedElements = new Tree(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ // selectedElements.addSelectionListener(this);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ selectedElements.setLayoutData(data);
+ selectedElementsViewer = new TreeViewer(selectedElements);
+
+ selectedElementsViewer.addSelectionChangedListener(this);
+ selectedElementsViewer.addDoubleClickListener(this);
+
+ selectedElementsViewer.setContentProvider(createListSectionContentProvider());
+
+ if (labelProvider != null) {
+ selectedElementsViewer.setLabelProvider(labelProvider);
+ }
+
+ selectedElementsViewer.setInput(allElements);
+ selector.setSelectedElements(allElements.toArray());
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.nattable.wizard.pages.MultipleValueSelectionWizard#createListSectionContentProvider()
+ *
+ * @return
+ * the content provider to use in the list section (right part)
+ */
+ protected IContentProvider createListSectionContentProvider() {
+ return CollectionContentProvider.instance;
+ }
+
+ /**
+ * Creates the up/down controls section
+ *
+ * @param parent
+ * The composite in which the section is created
+ */
+ protected void createRightButtonsSection(Composite parent) {
+ rightButtonsSection = new Composite(parent, SWT.NONE);
+ rightButtonsSection.setLayout(new GridLayout(1, true));
+
+ up = new Button(rightButtonsSection, SWT.PUSH);
+ up.setImage(Activator.getDefault().getImage("/icons/Up_12x12.gif")); //$NON-NLS-1$
+ up.addSelectionListener(this);
+ up.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsUp);
+
+ down = new Button(rightButtonsSection, SWT.PUSH);
+ down.setImage(Activator.getDefault().getImage("/icons/Down_12x12.gif")); //$NON-NLS-1$
+ down.addSelectionListener(this);
+ down.setToolTipText(Messages.MultipleValueEditor_MoveSelectedElementsDown);
+
+ create = new Button(rightButtonsSection, SWT.PUSH);
+ create.setImage(Activator.getDefault().getImage("/icons/Add_12x12.gif")); //$NON-NLS-1$
+ create.addSelectionListener(this);
+ create.setToolTipText(Messages.MultipleValueSelectorDialog_CreateNewElement);
+
+ delete = new Button(rightButtonsSection, SWT.PUSH);
+ delete.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ delete.addSelectionListener(this);
+ delete.setToolTipText(Messages.MultipleValueSelectorDialog_DeleteNewElement);
+ delete.setEnabled(false);
+ }
+
+ /**
+ * Sets the label provider used to display the selected elements
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ }
+
+ /**
+ * {@inheritDoc} Handles the events on one of the control buttons
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ *
+ * @param e
+ * The event that occurred
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == add) {
+ addAction();
+ } else if (e.widget == remove) {
+ removeAction();
+ } else if (e.widget == addAll) {
+ addAllAction();
+ } else if (e.widget == removeAll) {
+ removeAllAction();
+ } else if (e.widget == up) {
+ upAction();
+ } else if (e.widget == down) {
+ downAction();
+ } else if (e.widget == create) {
+ createAction();
+ } else if (e.widget == delete) {
+ deleteAction();
+ }
+
+ updateControls();
+ }
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this editor. The {@link ReferenceValueFactory} is used to create
+ * new instances and edit existing ones.
+ *
+ * @param factory
+ * The {@link ReferenceValueFactory} to be used by this editor
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.factory = factory;
+ updateControls();
+ }
+
+ /**
+ * Handles the "Add" action
+ */
+ protected void addAction() {
+ Object[] elements = selector.getSelectedElements();
+ addElements(elements);
+ }
+
+ /**
+ * Handles the "Up" action
+ */
+ protected void upAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(allElements);
+ for (Object o : selection.toArray()) {
+ int oldIndex = list.indexOf(o);
+ if (oldIndex > 0) {
+ move(list, oldIndex, oldIndex - 1);
+ }
+ }
+
+ allElements.clear();
+ allElements.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Down" action
+ */
+ protected void downAction() {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+
+ // We need a list to move objects. LinkedHashSet can't do that
+ java.util.List<Object> list = new LinkedList<Object>(allElements);
+
+ int maxIndex = list.size() - 1;
+
+ Object[] selectionArray = selection.toArray();
+ for (int i = selectionArray.length - 1; i >= 0; i--) {
+ Object o = selectionArray[i];
+ int oldIndex = list.indexOf(o);
+ if (oldIndex < maxIndex) {
+ move(list, oldIndex, oldIndex + 1);
+ }
+ }
+
+ allElements.clear();
+ allElements.addAll(list);
+
+ IStructuredSelection selectionCopy = new StructuredSelection(selection.toArray());
+ selectedElementsViewer.setSelection(selectionCopy);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Create" action
+ */
+ protected void createAction() {
+ if (factory == null) {
+ return;
+ }
+
+ Object newObject;
+
+ try {
+ newObject = factory.createObject(this.create, this.contextElement);
+ } catch (OperationCanceledException e) {
+ // The user cancelled and we rolled back pending model changes
+ newObject = null;
+ }
+
+ if (newObject == null) {
+ return;
+ }
+
+ newObjects.add(newObject);
+ selector.newObjectCreated(newObject);
+
+ Object[] createdObjects = new Object[] { newObject };
+ addElements(createdObjects);
+
+ selector.setSelectedElements(allElements.toArray());
+ }
+
+
+ /**
+ * Moves an element from oldIndex to newIndex
+ *
+ * @param list
+ * The list in which to move the object
+ * @param oldIndex
+ * @param newIndex
+ */
+ private void move(java.util.List<Object> list, int oldIndex, int newIndex) {
+ int size = list.size();
+
+ if (oldIndex < 0 || oldIndex >= size) {
+ throw new IndexOutOfBoundsException("oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (newIndex < 0 || newIndex >= size) {
+ throw new IndexOutOfBoundsException("newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ Object element = list.remove(oldIndex);
+ list.add(newIndex, element);
+ }
+
+ /**
+ * Handles the "Remove" action
+ */
+ protected void removeAction() {
+ if (canRemove()) {
+ IStructuredSelection selection = (IStructuredSelection) selectedElementsViewer.getSelection();
+ if (selection.isEmpty()) {
+ return;
+ }
+
+ for (Object element : selection.toArray()) {
+ allElements.remove(element);
+ }
+
+ selector.setSelectedElements(allElements.toArray());
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+ }
+
+ /**
+ * Handles the "Delete" action
+ */
+ protected void deleteAction() {
+ // nothing to do here
+ }
+
+ /**
+ * Handles the "Remove all" action
+ */
+ protected void removeAllAction() {
+ allElements.clear();
+ selector.setSelectedElements(new Object[0]);
+ selectedElementsViewer.setSelection(null);
+ selectedElementsViewer.refresh();
+ }
+
+ /**
+ * Handles the "Add All" action
+ */
+ protected void addAllAction() {
+ Object[] elements = selector.getAllElements();
+ addElements(elements);
+ }
+
+ /**
+ * Adds the specified elements to the currently selected elements (For
+ * "Add" and "Add all" actions)
+ *
+ * @param elements
+ * The elements to be added
+ */
+ @Override
+ public void addElements(Object[] elements) {
+ if (elements != null) {
+ allElements.addAll(Arrays.asList(elements));
+ selectedElementsViewer.refresh();
+ }
+ }
+
+ public List<Object> getSelection() {
+ if (factory != null) {
+ java.util.List<Object> objectsToValidate = new LinkedList<Object>();
+ for (Object object : newObjects) {
+ if (allElements.contains(object)) {
+ objectsToValidate.add(object);
+ }
+ }
+ factory.validateObjects(objectsToValidate);
+ selector.clearTemporaryElements();
+ }
+ return new LinkedList<Object>(allElements);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing (see #doubleClick())
+ }
+
+ /**
+ * Indicates if the selected values should be unique (According to Object.equals())
+ *
+ * @param unique
+ */
+ public void setUnique(boolean unique) {
+ this.unique = unique;
+ updateControls();
+ }
+
+ /**
+ * Indicates if the selected elements should be ordered
+ *
+ * @param ordered
+ */
+ public void setOrdered(boolean ordered) {
+ this.ordered = ordered;
+ updateControls();
+ }
+
+ public void updateControls() {
+ updateControl(up, ordered && canMove(true));
+ updateControl(down, ordered && canMove(false));
+ updateControl(create, this.factory != null && this.factory.canCreateObject());
+ updateControl(add, canAdd());
+ updateControl(delete, canDelete());
+ }
+
+ /**
+ * @return
+ */
+ protected boolean canDelete() {
+ return true;
+ }
+
+ /**
+ *
+ * @param up
+ * if <code>true</code> we try to move the element to the up, if <code>false</code> we try to move the element to the down
+ * @return
+ * <code>true</code> if the element can be moved
+ */
+ protected boolean canMove(boolean up) {
+ return ordered;
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> if we can add elements
+ */
+ protected boolean canAdd() {
+ /* Disable the bouton 'add' if the upperBound is reached */
+ boolean canAdd = true;
+ if (this.upperBound != ValueUtils.MANY) {
+ if (allElements.size() >= this.upperBound) {
+ canAdd = false;
+ }
+ }
+ return canAdd;
+ }
+
+ protected void updateControl(Control control, boolean enabled) {
+ if (control != null) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ public void setSelector(IElementSelector selector) {
+ this.selector = selector;
+ }
+
+ /**
+ * Set the maximum number of values selected.
+ *
+ * @param upperBound
+ */
+ public void setUpperBound(int upperBound) {
+ this.upperBound = upperBound;
+ }
+
+ /**
+ * Sets the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @param contextElement
+ * the model element that is being edited
+ */
+ public void setContextElement(Object contextElement) {
+ this.contextElement = contextElement;
+ }
+
+ /**
+ * Queries the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @return the model element that is being edited
+ */
+ public Object getContextElement() {
+ return contextElement;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Handles double click event on the right-panel tree viewer {@link #selectedElementsViewer}
+ *
+ */
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ removeAction();
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the selected elements can be removed (moved from right to left)
+ */
+ protected boolean canRemove() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Handles selection change event on the right-panel tree viewer {@link #selectedElementsViewer}
+ */
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateControls();
+ }
+
+ /**
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ selector.removeElementSelectionListener(this);
+ }
+
+ /**
+ *
+ * @return
+ * the initial selection
+ */
+ protected List<?> getInitialSelection() {
+ return this.initialSelection;
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWithCheckboxWidget.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWithCheckboxWidget.java
new file mode 100644
index 00000000000..dc5b301e481
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/widgets/MultipleValueSelectionWithCheckboxWidget.java
@@ -0,0 +1,168 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Adapted code from Camille Letavernier (CEA LIST) in MultipleValueSelectorDialog
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.widgets;
+
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * @author VL222926
+ *
+ *
+ */
+public class MultipleValueSelectionWithCheckboxWidget extends MultipleValueEditAndSelectionWidget {
+
+ /** boolean indicating if the checkbox is checked */
+ protected boolean isChecked;
+
+ /** The text to display for the checkbox */
+ protected String text;
+
+ /** the tooltip to display for the checkbox */
+ protected String tooltip;
+
+ /** indicates if the checkbox must be displayed or not */
+ protected boolean displayCheckBox = true;
+
+ protected Button checkBox;
+ /**
+ * the checkbox listener
+ */
+ protected SelectionListener checkboxListener;
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ * @param upperBound
+ */
+ public MultipleValueSelectionWithCheckboxWidget(IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ super(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ */
+ public MultipleValueSelectionWithCheckboxWidget(IElementSelector selector, boolean unique, boolean ordered) {
+ super(selector, unique, ordered);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ * @param unique
+ */
+ public MultipleValueSelectionWithCheckboxWidget(IElementSelector selector, boolean unique) {
+ super(selector, unique);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param selector
+ */
+ public MultipleValueSelectionWithCheckboxWidget(IElementSelector selector) {
+ super(selector);
+ }
+
+ /**
+ * @param text
+ * @param tooltip
+ * @param isChecked
+ */
+ public void setCheckBoxValues(String text, String tooltip, boolean isChecked) {
+ this.text = text;
+ this.tooltip = tooltip;
+ this.isChecked = isChecked;
+ }
+
+ /**
+ * @return
+ * <code>true</code> if the additional checkbox is checked
+ */
+ public boolean isChecked() {
+ return this.isChecked;
+ }
+
+ /**
+ * @param displayCheckBox
+ * <code>true</code> if the additional checkbox must be displayed
+ */
+ public void setDisplayCheckBox(boolean displayCheckBox) {
+ this.displayCheckBox = displayCheckBox;
+ }
+
+ /**
+ *
+ * @return <code>true</code> if the checkbox must be displayed
+ */
+ public boolean isDisplayingCheckBox() {
+ return this.displayCheckBox;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#createContents(org.eclipse.swt.widgets.Composite)
+ *
+ * @param parent
+ */
+ @Override
+ protected Composite createContents(Composite parent) {
+ Composite comp = super.createContents(parent);
+ if (this.displayCheckBox) {
+ this.checkBox = new Button(parent, SWT.CHECK);
+ this.checkBox.setText(this.text);
+ this.checkBox.setToolTipText(this.tooltip);
+ this.checkBox.setSelection(this.isChecked);
+ this.checkboxListener =
+ new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ isChecked = MultipleValueSelectionWithCheckboxWidget.this.checkBox.getSelection();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ };
+ this.checkBox.addSelectionListener(this.checkboxListener);
+ }
+ return comp;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ if (this.checkboxListener != null && this.checkBox != null) {
+ this.checkBox.removeSelectionListener(this.checkboxListener);
+ }
+ super.dispose();
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/wizard/pages/MultipleValueEditAndSelectionWizardPage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/wizard/pages/MultipleValueEditAndSelectionWizardPage.java
new file mode 100644
index 00000000000..8815c446a53
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/wizard/pages/MultipleValueEditAndSelectionWizardPage.java
@@ -0,0 +1,263 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.wizard.pages;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.editors.IElementSelector;
+import org.eclipse.papyrus.infra.widgets.util.ImageConstants;
+import org.eclipse.papyrus.infra.widgets.util.ValueUtils;
+import org.eclipse.papyrus.infra.widgets.widgets.MultipleValueSelectionWidget;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author VL222926
+ *
+ */
+public class MultipleValueEditAndSelectionWizardPage extends WizardPage {
+
+ /**
+ * the widget displayed in this dialog
+ */
+ private MultipleValueSelectionWidget widget;
+ /**
+ * The list of newly created objects
+ */
+ protected Set<Object> newObjects = new HashSet<Object>();
+
+ /**
+ * Constructor.
+ *
+ * @param pageName
+ * the name of the wizard page
+ * @param title
+ * the title of the page
+ * @param titleImage
+ * the image to use in the title
+ * @param selector
+ * The element selector used by this dialog
+ */
+ public MultipleValueEditAndSelectionWizardPage(String pageName, String title, ImageDescriptor titleImage, IElementSelector selector) {
+ this(pageName, title, titleImage, selector, false, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param pageName
+ * the name of the wizard page
+ * @param title
+ * the title of the page
+ * @param titleImage
+ * the image to use in the title
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueEditAndSelectionWizardPage(String pageName, String title, ImageDescriptor titleImage, IElementSelector selector, boolean unique) {
+ this(pageName, title, titleImage, selector, unique, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param pageName
+ * the name of the wizard page
+ * @param title
+ * the title of the page
+ * @param titleImage
+ * the image to use in the title
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ */
+ public MultipleValueEditAndSelectionWizardPage(String pageName, String title, ImageDescriptor titleImage, IElementSelector selector, boolean unique, boolean ordered) {
+ this(pageName, title, titleImage, selector, unique, false, ValueUtils.MANY);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param pageName
+ * the name of the wizard page
+ * @param title
+ * the title of the page
+ * @param titleImage
+ * the image to use in the title
+ * @param selector
+ * The element selector used by this dialog
+ * @param unique
+ * True if the values returned by this dialog should be unique
+ * @param upperBound
+ * The maximum number of values selected.
+ */
+ public MultipleValueEditAndSelectionWizardPage(String pageName, String title, ImageDescriptor titleImage, IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ super(pageName, title, titleImage);
+ this.widget = createWidget(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ *
+ * @param selector
+ * @param unique
+ * @param ordered
+ * @param upperBound
+ * @return
+ */
+ protected MultipleValueSelectionWidget createWidget(IElementSelector selector, boolean unique, boolean ordered, int upperBound) {
+ return new MultipleValueSelectionWidget(selector, unique, ordered, upperBound);
+ }
+
+ /**
+ * Sets the label provider used to display the selected elements
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.widget.setLabelProvider(labelProvider);
+ }
+
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this editor. The {@link ReferenceValueFactory} is used to create
+ * new instances and edit existing ones.
+ *
+ * @param factory
+ * The {@link ReferenceValueFactory} to be used by this editor
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.widget.setFactory(factory);
+ }
+
+ /**
+ * Indicates if the selected values should be unique (According to Object.equals())
+ *
+ * @param unique
+ */
+ public void setUnique(boolean unique) {
+ this.widget.setUnique(unique);
+ }
+
+ /**
+ * Indicates if the selected elements should be ordered
+ *
+ * @param ordered
+ */
+ public void setOrdered(boolean ordered) {
+ this.widget.setOrdered(ordered);
+ }
+
+ /**
+ *
+ * @param selector
+ */
+ public void setSelector(IElementSelector selector) {
+ this.widget.setSelector(selector);
+ }
+
+ /**
+ * Set the maximum number of values selected.
+ *
+ * @param upperBound
+ */
+ public void setUpperBound(int upperBound) {
+ this.widget.setUpperBound(upperBound);
+ }
+
+ /**
+ * Sets the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @param contextElement
+ * the model element that is being edited
+ */
+ public void setContextElement(Object contextElement) {
+ this.widget.setContextElement(contextElement);
+ }
+
+ /**
+ * Queries the optional context of the element that is being edited, in which others will be added and removed.
+ *
+ * @return the model element that is being edited
+ */
+ public Object getContextElement() {
+ return this.widget.getContextElement();
+ }
+
+
+ /**
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ *
+ * @param arg0
+ */
+ @Override
+ public void createControl(Composite arg0) {
+ Control ctrl = this.widget.create(arg0);
+ getShell().pack();
+ this.widget.updateControls();
+ setControl(ctrl);
+ }
+
+ /**
+ * @param arrayList
+ */
+ public void setInitialElementSelections(List<Object> arrayList) {
+ this.widget.setInitialSelections(arrayList);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ this.widget.dispose();
+ super.dispose();
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
+ *
+ * @param visible
+ */
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ getControl().setVisible(visible);
+ this.widget.updateControls();
+ getShell().pack();
+ }
+
+ /**
+ *
+ * @return
+ * the wrapped widget
+ */
+ protected MultipleValueSelectionWidget getWidget() {
+ return this.widget;
+ }
+}

Back to the top