Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-02-11 02:48:20 +0000
committerGerrit Code Review @ Eclipse.org2016-02-12 15:31:41 +0000
commitecd4928b327f5561364c5068c9ff5f1668e92d13 (patch)
tree7c34f46cf82a1d65ac753fa92c2a5d55371b8dba /plugins/infra/ui
parent751a204d74e15eb2db6b41c937691fc56dcc1252 (diff)
downloadorg.eclipse.papyrus-ecd4928b327f5561364c5068c9ff5f1668e92d13.tar.gz
org.eclipse.papyrus-ecd4928b327f5561364c5068c9ff5f1668e92d13.tar.xz
org.eclipse.papyrus-ecd4928b327f5561364c5068c9ff5f1668e92d13.zip
Bug 485220: [Architecture] Provide a more modular architecture
https://bugs.eclipse.org/bugs/show_bug.cgi?id=485220 Factor UI dependencies out of the UML Element Types bundle. This includes moving some advices that interact with the user into a new org.eclipse.papyrus.uml.service.types.ui bundle. Pull up the PasteCommandService and IPasteCommandProvider API into the Infra Diagram layer where the extension point is defined. Deprecate the old API in the UML layer. Introduce a service for participation of languages in CSS styling: * styling reset actions in the Reset Style command * access to semantic model classes and properties to make available to CSS Factor PapyrusObservableValue and cohorts out of the UML Tools bundle into the Infra Layer for more general reuse and to relieve the Diagram Infrastructure layer of UML dependencies. The old API remains as deprecated. Remove the Infra Diagram Layer dependency on UML Layer for property testers governing deletion in the diagram. Includes introduction of a new IGraphicalDeletionHelper OSGi service for delegation of the determination of whether an element can be deleted from the diagram and replacement of the XML expression properties * org.eclipse.papyrus.uml.diagram.common.isSemanticDeletion * org.eclipse.papyrus.uml.diagram.common.isReadOnly by * org.eclipse.papyrus.infra.gmfdiag.common.isSemanticDeletion * org.eclipse.papyrus.infra.gmfdiag.common.canDelete (where the latter is the negation of the property that it supersedes) Extract UML dependencies from the Diagram Outline and CSS Editor bundles. Remove unused MDTUtil APIs that referenced a UML-specific annotation. Move the Diagram Infrastructure CSS Palette bundle into the UML layer because it serves to provide extensions on the Palette Service, which is an overtly UML-specific capability. All client APIs for the Properties View are moved from org.eclipse.papyrus.views.properties bundle to a new org.eclipse.papyrus.infra.properties.ui bundle. This includes renaming of: * extension points * label-provider contexts * XWT namespaces Add an "all UI tests" suite. Define a componentized hierarchical build layout of the main plug-ins Change-Id: I43f8f3644857a18b69715f5a2f1da9b1cf286d67
Diffstat (limited to 'plugins/infra/ui')
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.classpath7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.project28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.core.prefs291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.ui.prefs68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/META-INF/MANIFEST.MF34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/about.html28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/build.properties7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/icons/papyrus.pngbin0 -> 602 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.properties15
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.xml305
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/pom.xml12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/Activator.java61
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/CopyFilesAndFoldersOperation.java1969
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusCopyFilesAndFoldersOperation.java265
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusModelPasteAction.java50
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PasteAction.java268
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/filters/OnlyDiFilter.java57
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/ModelAdapterFactory.java42
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusCommonDropAdapterAssistant.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusLinkHelper.java70
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusModelContributorResourceAdapter.java38
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/SubResourceAdapterFactory.java41
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/CopyToClipboardAction.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/OneFileDecorator.java179
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusEditActionProvider.java142
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusModelActionProvider.java479
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/SubresourceFileActionProvider.java77
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/testers/PapyrusClipboardTester.java78
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusContentProvider.java307
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusLabelProvider.java84
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusViewerSorter.java54
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/utils/OneFileUIUtils.java210
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.classpath7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.project28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.core.prefs291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.ui.prefs68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/META-INF/MANIFEST.MF22
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/about.html28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/build.properties11
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.properties15
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.xml21
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/pom.xml12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/Activator.java72
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/DirtyEditorChange.java146
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/Messages.java66
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ModelParticipantHelpers.java126
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelChange.java532
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelParticipant.java272
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/messages.properties19
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/IScopeChooser.java50
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/Messages.java35
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/RenameParticipantsDialog.java211
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/ScopeChooser.java99
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/messages.properties23
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/.classpath7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/.gitignore2
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/.project29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.core.prefs291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.ui.prefs68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF54
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/about.html28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/build.properties10
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/PapyrusLogo32x32.pngbin0 -> 2001 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/Papyrus_32x32_t.gifbin0 -> 1264 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus.gifbin0 -> 561 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus_16x16.gifbin0 -> 561 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.properties13
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.xml533
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml13
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/contentOutline.exsd144
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/papyrusDiagram.exsd342
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/Activator.java99
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractCommandHandler.java189
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractPapyrusHandler.java217
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/ContentOutlineRegistry.java263
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/IPapyrusContentOutlinePage.java34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/NestedEditorDelegatedOutlinePage.java1098
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/AbstractStringValueConverter.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/ConvertedValueContainer.java75
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/EMFStringValueConverter.java373
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/IStringValueConverter.java36
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/MultiConvertedValueContainer.java39
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/StringValueConverterStatus.java60
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/dnd/PapyrusTransfer.java105
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/ContentProviderServiceFactory.java68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java1244
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelManagerServiceFactory.java114
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelMngrServiceFactory.java101
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IMultiDiagramEditor.java93
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IPapyrusPageInput.java35
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IReloadableEditor.java409
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramEditorSelectionContext.java291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramPropertySheetPage.java178
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageIconRegistryServiceFactory.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageMngrServiceFactory.java83
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PapyrusPageInput.java62
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/CompositeReloadContext.java86
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/DelegatingReloadContext.java74
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFSelectionContext.java52
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFTreeViewerContext.java52
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadAdapter.java36
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadEvent.java188
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IDisposableReloadContext.java23
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IEditorReloadListener.java44
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IInternalEMFSelectionContext.java109
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IReloadContextProvider.java38
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/SelectionContext.java81
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/TreeViewerContext.java64
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/AbstractGetEditorIconQuery.java74
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorFactory.java57
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactory.java64
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactoryExtended.java30
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistry.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistryExtended.java32
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageIconsRegistry.java118
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageModelFactoryRegistry.java165
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/anytype/AnyTypeEditorFactory.java135
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/ICreationCondition.java36
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/IModelCreationCommand.java31
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/PerspectiveContextDependence.java51
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/AbstractEditorFactory.java109
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptor.java168
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptorExtensionFactory.java99
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorFactoryProxy.java137
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorIconFactory.java152
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorNotFoundException.java53
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/IPluggableEditorFactory.java39
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/MultiDiagramException.java53
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/PluggableEditorFactoryReader.java143
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/PageLayoutStorageState.java164
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/SashLayoutCommandFactory.java226
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/TogglePageLayoutStorageHandler.java78
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferencePage.java52
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferences.java88
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/Messages.java37
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/YesNo.java21
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/messages.properties18
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/DoSaveEvent.java66
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/IEditorInputChangedListener.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ILifeCycleEventsProvider.java57
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveAndDirtyService.java56
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveEventListener.java27
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProvider.java291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProviderServiceFactory.java79
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/SaveAndDirtyService.java550
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractCommonCommandHandler.java98
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractEMFParametricOnSelectedElementsAction.java61
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractParametricOnSelectedElementsAction.java115
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalization.java24
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalizationCommand.java124
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NamePropertyTester.java41
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/Messages.java48
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/messages.properties10
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java72
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java72
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java176
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java122
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/IActionBarContributorFactory.java25
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferencePage.java237
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferenceStore.java300
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPreferenceGroup.java161
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/IPapyrusPreferencePage.java28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/PapyrusScopedPreferenceStore.java858
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/VisiblePageSingleton.java67
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractApplyValueOnPreferenceKeyDialog.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractPreferenceKeyDialog.java105
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositePapyrusContentProvider.java109
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositeSemanticContentProviderFactory.java63
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/DelegatingPapyrusContentProvider.java170
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/ISemanticContentProviderFactory.java59
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleEventListener.java55
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleManager.java30
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/Messages.java34
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/ResourceUpdateService.java292
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/SaveLayoutBeforeClose.java218
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/EditorLifecycleManagerImpl.java128
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/InternalEditorLifecycleManager.java48
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/messages.properties15
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/AbstractCreateMenuFromCommandCategory.java135
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/DisplayUtils.java47
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EclipseCommandUtils.java137
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorHelper.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java721
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ICallableWithProgress.java50
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/LocalMemento.java285
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/PapyrusImageUtils.java67
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/SelectionHelper.java119
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForActionHandlers.java149
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForHandlers.java122
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForIEvaluationContext.java113
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForSelection.java61
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForWorkbenchPage.java63
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/TransactionUIHelper.java81
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/UIUtil.java706
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/WorkbenchPartHelper.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.classpath7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.project28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.core.prefs291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.ui.prefs68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/META-INF/MANIFEST.MF28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/about.html28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/build.properties7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/run.gifbin0 -> 379 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/sample.gifbin0 -> 963 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.properties12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.xml41
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/pom.xml12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/schema/papyrusNotificationBuilder.exsd121
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/Activator.java99
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/SwtUtil.java167
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/dialog/InformationDialog.java133
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/draw2d/ManuallyDrawnShortcutDecorationFigure.java71
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/IBuilder.java47
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICallBack.java29
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICompositeCreator.java35
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/INotification.java23
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/NotificationRunnable.java36
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/PapyrusToolkit.java48
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/Type.java23
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/AsyncNotifierBuilder.java128
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/CombinedPopupAndViewBuilder.java147
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/IContext.java41
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/NotificationBuilder.java546
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PopupBuilder.java112
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PropertyWrapper.java189
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/ViewBuilder.java125
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AbstractNotificationPopup.java583
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AsyncNotification.java51
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/CommonFonts.java106
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/ImagePapyrusAsyncNotificationPopup.java69
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/NotificationPopupColors.java187
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusAsyncNotificationPopup.java139
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusPopup.java222
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/exception/NotificationException.java40
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/IconAndMessagePapyrusPopup.java67
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/MessagePapyrusPopup.java74
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/PopupNotification.java63
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/utils/PapyrusControlsFactory.java128
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/AbstractInsideComposite.java174
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/MessageComposite.java50
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/PapyrusNotificationView.java417
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/ViewNotification.java44
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/DialogUtils.java122
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ISharedImages.java25
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ToolbooxImageUtils.java78
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.checkstyle7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.classpath7
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.project28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.core.resources.prefs2
-rwxr-xr-xplugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.core.prefs291
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.ui.prefs68
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF36
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/about.html28
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/build.properties12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/AddReg.gifbin0 -> 328 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_12x12.gifbin0 -> 345 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_16x16.gifbin0 -> 318 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowDown_16x16.gifbin0 -> 332 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowUp_16x16.gifbin0 -> 323 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_12x12.gifbin0 -> 367 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_16x16.gifbin0 -> 351 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Down_12x12.gifbin0 -> 308 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_12x12.gifbin0 -> 204 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_16x16.gifbin0 -> 322 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/PapyrusLogo16x16.gifbin0 -> 561 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Switch_12x12.gifbin0 -> 304 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Up_12x12.gifbin0 -> 338 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_double.gifbin0 -> 594 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left.gifbin0 -> 327 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left_double.gifbin0 -> 597 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_right.gifbin0 -> 541 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-filesystem_12x12.pngbin0 -> 392 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-workspace_12x12.pngbin0 -> 458 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse_12x12.gifbin0 -> 84 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/error.gifbin0 -> 353 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/hyperlink_16x16.gifbin0 -> 596 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/papyrus.pngbin0 -> 602 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/refresh.gifbin0 -> 330 bytes
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.properties13
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.xml12
-rw-r--r--plugins/infra/ui/org.eclipse.papyrus.infra.widgets/pom.xml12
-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
-rw-r--r--plugins/infra/ui/pom.xml21
437 files changed, 54951 insertions, 0 deletions
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.classpath b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.classpath
new file mode 100644
index 00000000000..64c5e31b7a2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.project b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.project
new file mode 100644
index 00000000000..2520b07362d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.infra.onefile.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..c585cc455ae
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,291 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=260
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=260
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.ui.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..954281dbc31
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,68 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Papyrus
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Papyrus
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..fc586354cf3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,34 @@
+Manifest-Version: 1.0
+Export-Package: org.eclipse.papyrus.infra.onefile.internal.ui;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.internal.ui.action;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.internal.ui.filters;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.internal.ui.providers;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.internal.ui.testers;x-internal:=true,
+ org.eclipse.papyrus.infra.onefile.ui.providers,
+ org.eclipse.papyrus.infra.onefile.ui.utils
+Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
+ org.eclipse.ui.navigator,
+ org.eclipse.ui.navigator.resources,
+ org.eclipse.core.resources;bundle-version="3.7.0",
+ org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.ui,
+ org.eclipse.ui.ide;bundle-version="3.8.0",
+ org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
+ org.eclipse.ltk.core.refactoring;bundle-version="3.6.0",
+ org.eclipse.ltk.ui.refactoring;bundle-version="3.7.0",
+ org.eclipse.core.filesystem;bundle-version="1.4.0",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.2.0",
+ org.eclipse.core.expressions,
+ org.eclipse.emf.ecore;bundle-version="2.12.0",
+ org.eclipse.papyrus.infra.ui;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.onefile;bundle-version="1.2.0"
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.2.0.qualifier
+Bundle-Localization: plugin
+Bundle-Name: %pluginName
+Bundle-Activator: org.eclipse.papyrus.infra.onefile.internal.ui.Activator
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.papyrus.infra.onefile.ui;singleton:=true
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/about.html b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/about.html
new file mode 100644
index 00000000000..dd3c089a94c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 14, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/build.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/build.properties
new file mode 100644
index 00000000000..082c8b2f4f1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/build.properties
@@ -0,0 +1,7 @@
+#
+#Mon Sep 12 09:29:59 CEST 2011
+bin.includes=META-INF/,.,plugin.xml,icons/,about.html,plugin.properties
+output..=bin/
+src.includes = about.html
+source..=src/
+bin..=bin/
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/icons/papyrus.png b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/icons/papyrus.png
new file mode 100644
index 00000000000..0f74e27b483
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/icons/papyrus.png
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.properties
new file mode 100644
index 00000000000..1bc9dea55df
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.properties
@@ -0,0 +1,15 @@
+#################################################################################
+# Copyright (c) 2011, 2016 Atos Origin, 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:
+# Vincent Hemery vincent.hemery@atos.net - Initial API and implementation
+# Christian W. Damus - bug 485220
+#
+##################################################################################
+pluginName=Papyrus Onefile UI
+providerName=Eclipse Modeling Project \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.xml
new file mode 100644
index 00000000000..f64926b75c3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/plugin.xml
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile"
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters.ModelAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.ide.IContributorResourceAdapter2">
+ </adapter>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile"
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters.SubResourceAdapterFactory">
+ <adapter
+ type="org.eclipse.ui.IContributorResourceAdapter">
+ </adapter>
+ <adapter
+ type="org.eclipse.ui.ide.IContributorResourceAdapter2">
+ </adapter>
+ </factory>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.navigator.navigatorContent">
+ <commonFilter
+ activeByDefault="true"
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.filters.OnlyDiFilter"
+ description="All the files related to di files are agregated bellow a common parent"
+ id="org.eclipse.papyrus.infra.onefile.onlyDiFilter"
+ name="Di view"
+ visibleInUI="true">
+ </commonFilter>
+ <navigatorContent
+ activeByDefault="true"
+ contentProvider="org.eclipse.papyrus.infra.onefile.ui.providers.PapyrusContentProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent"
+ labelProvider="org.eclipse.papyrus.infra.onefile.ui.providers.PapyrusLabelProvider"
+ name="Papyrus Content"
+ priority="high">
+ <enablement>
+ <or>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.providers.OneFileModelProvider">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.resources.IResource">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.internal.resources.mapping.ResourceModelProvider">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.resources.IFile">
+ </instanceof>
+ <adapt
+ type="org.eclipse.core.resources.IResource">
+ </adapt>
+ </or>
+ </enablement>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.providers.PapyrusModelActionProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.OpenActions"
+ overrides="org.eclipse.ui.navigator.resources.OpenActions">
+ <enablement>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ </enablement>
+ </actionProvider>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.providers.PapyrusEditActionProvider"
+ dependsOn="org.eclipse.ui.navigator.resources.actions.EditActions"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.EditActions">
+ <enablement>
+ <and>
+ <with
+ variable="activeShell">
+ <test
+ property="org.eclipse.papyrus.infra.onefile.handlers.tester.containsPapyrusModel"
+ value="true">
+ </test>
+ </with>
+ </and>
+ </enablement>
+ </actionProvider>
+ <dropAssistant
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters.PapyrusCommonDropAdapterAssistant"
+ id="org.eclipse.papyrus.infra.onefile.PapyrusDropAssistant">
+ <possibleDropTargets>
+ <instanceof
+ value="org.eclipse.core.resources.IContainer">
+ </instanceof>
+ </possibleDropTargets>
+ </dropAssistant>
+ <commonSorter
+ class="org.eclipse.papyrus.infra.onefile.ui.providers.PapyrusViewerSorter"
+ id="org.eclipse.papyrus.infra.onefile.sorter">
+ </commonSorter>
+ <triggerPoints>
+ <or>
+ <instanceof
+ value="org.eclipse.core.resources.IContainer">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
+ </instanceof>
+ </or>
+ </triggerPoints>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.providers.SubresourceFileActionProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.EditActions">
+ <enablement>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
+ </instanceof>
+ </enablement>
+ </actionProvider>
+ </navigatorContent>
+ </extension>
+
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewerContentBinding viewerId="org.eclipse.team.ui.navigatorViewer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.jdt.ui.PackageExplorer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resourceContent" />
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resources.filters.*"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.ui.navigator.ProjectExplorer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resourceContent" />
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resources.filters.*"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.ui.navigatorViewer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.svn.ui.workspaceSynchronization">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.cvs.ui.workspaceSynchronization">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.papyrus.infra.onefile.DiContent">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.jdt.java.ui.javaContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.navigator.linkHelper">
+ <linkHelper
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters.PapyrusLinkHelper"
+ id="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ <editorInputEnablement>
+ <and>
+ <instanceof
+ value="org.eclipse.ui.IFileEditorInput">
+ </instanceof>
+ <adapt
+ type="org.eclipse.core.resources.IFile">
+ <test
+ property="org.eclipse.core.resources.extension"
+ value="di">
+ </test>
+ </adapt>
+ </and>
+ </editorInputEnablement>
+ <selectionEnablement>
+ <or>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <and>
+ <instanceof
+ value="org.eclipse.core.resources.IFile">
+ </instanceof>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.core.resources.extension"
+ value="di">
+ </test>
+ </and>
+ </or>
+ </selectionEnablement>
+ </linkHelper>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.decorators">
+ <decorator
+ adaptable="true"
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.providers.OneFileDecorator"
+ id="org.eclipse.papyrus.infra.onefile.onefiledecorator"
+ label="One File Decorator"
+ lightweight="true"
+ state="true">
+ <enablement>
+ <objectClass
+ name="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </objectClass>
+ </enablement>
+ </decorator>
+ </extension>
+
+ <extension
+ point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.testers.PapyrusClipboardTester"
+ id="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ namespace="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ properties="containsPapyrusModel"
+ type="org.eclipse.swt.widgets.Shell">
+ </propertyTester>
+ <propertyTester
+ class="org.eclipse.papyrus.infra.onefile.internal.ui.testers.PapyrusClipboardTester"
+ id="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ namespace="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ properties="toto"
+ type="java.util.Collection">
+ </propertyTester>
+ </extension>
+
+ <!-- #368878 : Definition of command id to avoid error logs -->
+ <extension
+ id="org.eclipse.ui.commands.oneFile"
+ name="Commands for oneFiles"
+ point="org.eclipse.ui.commands">
+ <command name="Move file"
+ description="Move file"
+ categoryId="org.eclipse.ui.category.file"
+ id="move">
+ </command>
+ <command name="Open selected file"
+ description="Open selected fsile"
+ categoryId="org.eclipse.ui.category.file"
+ id="org.eclipse.ui.navigator.Open">
+ </command>
+ </extension>
+
+</plugin>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/pom.xml
new file mode 100644
index 00000000000..18f26289ae9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.infra.onefile.ui</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/Activator.java
new file mode 100644
index 00000000000..14f957c2394
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/Activator.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 Atos Origin Integration, 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+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.onefile.ui"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(this);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/CopyFilesAndFoldersOperation.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/CopyFilesAndFoldersOperation.java
new file mode 100644
index 00000000000..aefe0637a67
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/CopyFilesAndFoldersOperation.java
@@ -0,0 +1,1969 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Serge Beauchamp (Freescale Semiconductor) - [229633] Group Support
+ *******************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.action;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileInfo;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.ide.dialogs.ImportTypeDialog;
+import org.eclipse.ui.ide.undo.AbstractWorkspaceOperation;
+import org.eclipse.ui.ide.undo.CopyResourcesOperation;
+import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.internal.ide.IDEInternalPreferences;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.ide.StatusUtil;
+import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.wizards.datatransfer.FileStoreStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+
+
+/**
+ * Perform the copy of file and folder resources from the clipboard when paste
+ * action is invoked.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CopyFilesAndFoldersOperation {
+
+ /**
+ * Status containing the errors detected when running the operation or <code>null</code> if no errors detected.
+ */
+ private MultiStatus errorStatus;
+
+ /**
+ * The parent shell used to show any dialogs.
+ */
+ protected Shell messageShell;
+
+ /**
+ * Whether or not the copy has been canceled by the user.
+ */
+ private boolean canceled = false;
+
+ /**
+ * Whether or not the operation creates virtual folders and links instead of folders
+ * and files.
+ */
+ private boolean createVirtualFoldersAndLinks = false;
+
+ /**
+ * Whether or not the operation creates links instead of folders and files.
+ */
+ private boolean createLinks = false;
+
+ private String relativeVariable = null;
+ /**
+ * Overwrite all flag.
+ */
+ private boolean alwaysOverwrite = false;
+
+ private String[] modelProviderIds;
+
+ /**
+ * Returns a new name for a copy of the resource at the given path in the
+ * given workspace. This name is determined automatically.
+ *
+ * @param originalName
+ * the full path of the resource
+ * @param workspace
+ * the workspace
+ * @return the new full path for the copy
+ */
+ static IPath getAutoNewNameFor(IPath originalName, IWorkspace workspace) {
+ String resourceName = originalName.lastSegment();
+ IPath leadupSegment = originalName.removeLastSegments(1);
+ boolean isFile = !originalName.hasTrailingSeparator();
+
+ String newName = computeNewName(resourceName, isFile);
+ while (true) {
+ IPath pathToTry = leadupSegment.append(newName);
+ if (!workspace.getRoot().exists(pathToTry)) {
+ return pathToTry;
+ }
+ newName = computeNewName(newName, isFile);
+ }
+ }
+
+ private static String computeNewName(String str, boolean isFile) {
+ int lastIndexOfDot = str.lastIndexOf('.');
+ String fileExtension = ""; //$NON-NLS-1$
+ String fileNameNoExtension = str;
+ if (isFile && lastIndexOfDot > 0) {
+ fileExtension = str.substring(lastIndexOfDot);
+ fileNameNoExtension = str.substring(0, lastIndexOfDot);
+ }
+ Pattern p = Pattern.compile("[0-9]+$"); //$NON-NLS-1$
+ Matcher m = p.matcher(fileNameNoExtension);
+ if (m.find()) {
+ // String ends with a number: increment it by 1
+ int newNumber = Integer.parseInt(m.group()) + 1;
+ String numberStr = m.replaceFirst(Integer.toString(newNumber));
+ return numberStr + fileExtension;
+ }
+ return fileNameNoExtension + "2" + fileExtension; //$NON-NLS-1$
+ }
+
+ /**
+ * Creates a new operation initialized with a shell.
+ *
+ * @param shell
+ * parent shell for error dialogs
+ */
+ public CopyFilesAndFoldersOperation(Shell shell) {
+ messageShell = shell;
+ }
+
+ /**
+ * Returns whether this operation is able to perform on-the-fly
+ * auto-renaming of resources with name collisions.
+ *
+ * @return <code>true</code> if auto-rename is supported, and <code>false</code> otherwise
+ */
+ protected boolean canPerformAutoRename() {
+ return true;
+ }
+
+ /**
+ * Returns the message for querying deep copy/move of a linked resource.
+ *
+ * @param source
+ * resource the query is made for
+ * @return the deep query message
+ */
+ protected String getDeepCheckQuestion(IResource source) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepCopyQuestion,
+ source.getFullPath().makeRelative());
+ }
+
+ /**
+ * Checks whether the infos exist.
+ *
+ * @param stores
+ * the file infos to test
+ * @return Multi status with one error message for each missing file.
+ */
+ IStatus checkExist(IFileStore[] stores) {
+ MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.OK, getProblemsMessage(), null);
+
+ for (int i = 0; i < stores.length; i++) {
+ if (stores[i].fetchInfo().exists() == false) {
+ String message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ stores[i].getName());
+ IStatus status = new Status(IStatus.ERROR,
+ PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
+ multiStatus.add(status);
+ }
+ }
+ return multiStatus;
+ }
+
+ /**
+ * Checks whether the resources with the given names exist.
+ *
+ * @param resources
+ * IResources to checl
+ * @return Multi status with one error message for each missing file.
+ */
+ IStatus checkExist(IResource[] resources) {
+ MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.OK, getProblemsMessage(), null);
+
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (resource != null && !resource.isVirtual()) {
+ URI location = resource.getLocationURI();
+ String message = null;
+ if (location != null) {
+ IFileInfo info = IDEResourceInfoUtils.getFileInfo(location);
+ if (info == null || info.exists() == false) {
+ if (resource.isLinked()) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingLinkTarget,
+ resource.getName());
+ } else {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ resource.getName());
+ }
+ }
+ }
+ if (message != null) {
+ IStatus status = new Status(IStatus.ERROR,
+ PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
+ multiStatus.add(status);
+ }
+ }
+ }
+ return multiStatus;
+ }
+
+ /**
+ * Check if the user wishes to overwrite the supplied resource or all
+ * resources.
+ *
+ * @param source
+ * the source resource
+ * @param destination
+ * the resource to be overwritten
+ * @return one of IDialogConstants.YES_ID, IDialogConstants.YES_TO_ALL_ID,
+ * IDialogConstants.NO_ID, IDialogConstants.CANCEL_ID indicating
+ * whether the current resource or all resources can be overwritten,
+ * or if the operation should be canceled.
+ */
+ private int checkOverwrite(final IResource source,
+ final IResource destination) {
+ final int[] result = new int[1];
+
+ // Dialogs need to be created and opened in the UI thread
+ Runnable query = new Runnable() {
+ public void run() {
+ String message;
+ int resultId[] = { IDialogConstants.YES_ID,
+ IDialogConstants.YES_TO_ALL_ID, IDialogConstants.NO_ID,
+ IDialogConstants.CANCEL_ID };
+ String labels[] = new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+
+ if (destination.getType() == IResource.FOLDER) {
+ if (homogenousResources(source, destination)) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteMergeQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ } else {
+ if (destination.isLinked()) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeLinkQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ } else {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeNoLinkQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ }
+ resultId = new int[] { IDialogConstants.YES_ID,
+ IDialogConstants.NO_ID,
+ IDialogConstants.CANCEL_ID };
+ labels = new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+ }
+ } else {
+ String[] bindings = new String[] {
+ IDEResourceInfoUtils.getLocationText(destination),
+ IDEResourceInfoUtils
+ .getDateStringValue(destination),
+ IDEResourceInfoUtils.getLocationText(source),
+ IDEResourceInfoUtils.getDateStringValue(source) };
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteWithDetailsQuestion,
+ bindings);
+ }
+ MessageDialog dialog = new MessageDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceExists,
+ null, message, MessageDialog.QUESTION, labels, 0) {
+ @Override
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ dialog.open();
+ if (dialog.getReturnCode() == SWT.DEFAULT) {
+ // A window close returns SWT.DEFAULT, which has to be
+ // mapped to a cancel
+ result[0] = IDialogConstants.CANCEL_ID;
+ } else {
+ result[0] = resultId[dialog.getReturnCode()];
+ }
+ }
+ };
+ messageShell.getDisplay().syncExec(query);
+ return result[0];
+ }
+
+ /**
+ * Recursively collects existing files in the specified destination path.
+ *
+ * @param destinationPath
+ * destination path to check for existing files
+ * @param copyResources
+ * resources that may exist in the destination
+ * @param existing
+ * holds the collected existing files
+ */
+ private void collectExistingReadonlyFiles(IPath destinationPath,
+ IResource[] copyResources, ArrayList existing) {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+ for (int i = 0; i < copyResources.length; i++) {
+ IResource source = copyResources[i];
+ IPath newDestinationPath = destinationPath.append(source.getName());
+ IResource newDestination = workspaceRoot
+ .findMember(newDestinationPath);
+ IFolder folder;
+
+ if (newDestination == null) {
+ continue;
+ }
+ folder = getFolder(newDestination);
+ if (folder != null) {
+ IFolder sourceFolder = getFolder(source);
+
+ if (sourceFolder != null) {
+ try {
+ collectExistingReadonlyFiles(newDestinationPath,
+ sourceFolder.members(), existing);
+ } catch (CoreException exception) {
+ recordError(exception);
+ }
+ }
+ } else {
+ IFile file = getFile(newDestination);
+
+ if (file != null) {
+ if (file.isReadOnly()) {
+ existing.add(file);
+ }
+ if (getValidateConflictSource()) {
+ IFile sourceFile = getFile(source);
+ if (sourceFile != null) {
+ existing.add(sourceFile);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Copies the resources to the given destination. This method is called
+ * recursively to merge folders during folder copy.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @param subMonitor
+ * a progress monitor for showing progress and for cancelation
+ *
+ * @deprecated As of 3.3, the work is performed in the undoable operation
+ * created in {@link #getUndoableCopyOrMoveOperation(IResource[], IPath)}
+ */
+ @Deprecated
+ protected void copy(IResource[] resources, IPath destination,
+ IProgressMonitor subMonitor) throws CoreException {
+
+ subMonitor
+ .beginTask(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_CopyResourcesTask,
+ resources.length);
+
+ for (int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ IPath destinationPath = destination.append(source.getName());
+ IWorkspace workspace = source.getWorkspace();
+ IWorkspaceRoot workspaceRoot = workspace.getRoot();
+ IResource existing = workspaceRoot.findMember(destinationPath);
+ if (source.getType() == IResource.FOLDER && existing != null) {
+ // the resource is a folder and it exists in the destination,
+ // copy the
+ // children of the folder.
+ if (homogenousResources(source, existing)) {
+ IResource[] children = ((IContainer) source).members();
+ copy(children, destinationPath, new SubProgressMonitor(
+ subMonitor, 1));
+ } else {
+ // delete the destination folder, copying a linked folder
+ // over an unlinked one or vice versa. Fixes bug 28772.
+ delete(existing, new SubProgressMonitor(subMonitor, 0));
+ source.copy(destinationPath, IResource.SHALLOW,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+ } else {
+ if (existing != null) {
+ if (homogenousResources(source, existing)) {
+ copyExisting(source, existing, new SubProgressMonitor(
+ subMonitor, 1));
+ } else {
+ if (existing != null) {
+ // Copying a linked resource over unlinked or vice
+ // versa.
+ // Can't use setContents here. Fixes bug 28772.
+ delete(existing, new SubProgressMonitor(subMonitor, 0));
+ }
+
+ if ((createLinks || createVirtualFoldersAndLinks)
+ && (source.isLinked() == false)
+ && (source.isVirtual() == false)) {
+ if (source.getType() == IResource.FILE) {
+ IFile file = workspaceRoot.getFile(destinationPath);
+ file.createLink(createRelativePath(source.getLocationURI(), file), 0,
+ new SubProgressMonitor(subMonitor, 1));
+ } else {
+ IFolder folder = workspaceRoot
+ .getFolder(destinationPath);
+ if (createVirtualFoldersAndLinks) {
+ folder.create(IResource.VIRTUAL, true,
+ new SubProgressMonitor(subMonitor,
+ 1));
+ IResource[] members = ((IContainer) source)
+ .members();
+ if (members.length > 0) {
+ copy(members, destinationPath,
+ new SubProgressMonitor(subMonitor,
+ 1));
+ }
+ } else {
+ folder.createLink(createRelativePath(source.getLocationURI(), folder), 0,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+ }
+ } else {
+ source.copy(destinationPath, IResource.SHALLOW,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+ }
+
+ if (subMonitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Transform an absolute path URI to a relative path one (i.e. from
+ * "C:\foo\bar\file.txt" to "VAR\file.txt" granted that the relativeVariable
+ * is "VAR" and points to "C:\foo\bar\").
+ *
+ * @param locationURI
+ * @return an URI that was made relative to a variable
+ */
+ private URI createRelativePath(URI locationURI, IResource resource) {
+ if (relativeVariable == null) {
+ return locationURI;
+ }
+ IPath location = URIUtil.toPath(locationURI);
+ IPath result;
+ try {
+ result = URIUtil.toPath(resource.getPathVariableManager().convertToRelative(URIUtil.toURI(location), true, relativeVariable));
+ } catch (CoreException e) {
+ return locationURI;
+ }
+ return URIUtil.toURI(result);
+ }
+
+ /**
+ * Sets the content of the existing file to the source file content.
+ *
+ * @param source
+ * source file to copy
+ * @param existing
+ * existing file to set the source content in
+ * @param subMonitor
+ * a progress monitor for showing progress and for cancelation
+ * @throws CoreException
+ * setContents failed
+ */
+ private void copyExisting(IResource source, IResource existing,
+ IProgressMonitor subMonitor) throws CoreException {
+ IFile existingFile = getFile(existing);
+
+ if (existingFile != null) {
+ IFile sourceFile = getFile(source);
+
+ if (sourceFile != null) {
+ existingFile.setContents(sourceFile.getContents(),
+ IResource.KEEP_HISTORY, new SubProgressMonitor(
+ subMonitor, 0));
+ }
+ }
+ }
+
+ /**
+ * Copies the given resources to the destination. The current Thread is
+ * halted while the resources are copied using a WorkspaceModifyOperation.
+ * This method should be called from the UIThread.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @return the resources which actually got copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ */
+ public IResource[] copyResources(final IResource[] resources,
+ IContainer destination) {
+ return copyResources(resources, destination, true);
+ }
+
+ /**
+ * Copies the given resources to the destination in the current Thread
+ * without forking a new Thread or blocking using a
+ * WorkspaceModifyOperation. It recommended that this method only be called
+ * from a {@link WorkspaceJob} to avoid possible deadlock.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @return IResource[] the resulting {@link IResource}[]
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public IResource[] copyResourcesInCurrentThread(
+ final IResource[] resources, IContainer destination,
+ IProgressMonitor monitor) {
+ return copyResources(resources, destination, false);
+ }
+
+ /**
+ * Copies the given resources to the destination.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @return IResource[] the resulting {@link IResource}[]
+ */
+ private IResource[] copyResources(final IResource[] resources,
+ IContainer destination, boolean fork) {
+ final IPath destinationPath = destination.getFullPath();
+ final IResource[][] copiedResources = new IResource[1][0];
+
+ // test resources for existence separate from validate API.
+ // Validate is performance critical and resource exists
+ // check is potentially slow. Fixes bugs 16129/28602.
+ IStatus resourceStatus = checkExist(resources);
+ if (resourceStatus.getSeverity() != IStatus.OK) {
+ displayError(resourceStatus);
+ return copiedResources[0];
+ }
+ String errorMsg = validateDestination(destination, resources);
+ if (errorMsg != null) {
+ displayError(errorMsg);
+ return copiedResources[0];
+ }
+
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ copyResources(resources, destinationPath, copiedResources,
+ monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(fork, true, op);
+ } catch (InterruptedException e) {
+ return copiedResources[0];
+ } catch (InvocationTargetException e) {
+ display(e);
+ }
+
+ // If errors occurred, open an Error dialog
+ if (errorStatus != null) {
+ displayError(errorStatus);
+ errorStatus = null;
+ }
+
+ return copiedResources[0];
+ }
+
+ /**
+ * Return whether the operation is a move or a copy
+ *
+ * @return whether the operation is a move or a copy
+ * @since 3.2
+ */
+ protected boolean isMove() {
+ return false;
+ }
+
+ private void display(InvocationTargetException e) {
+ // CoreExceptions are collected above, but unexpected runtime
+ // exceptions and errors may still occur.
+ String format = "Exception in " + getClass().getName() + ".performCopy(): " + e.getTargetException();
+
+ IDEWorkbenchPlugin.getDefault().getLog().log(
+ StatusUtil.newStatus(IStatus.ERROR, format, null));
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ e.getTargetException().getMessage()));
+ }
+
+ /**
+ * Copies the given URIS and folders to the destination. The current Thread
+ * is halted while the resources are copied using a
+ * WorkspaceModifyOperation. This method should be called from the UI
+ * Thread.
+ *
+ * @param uris
+ * the URIs to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.2
+ */
+ public void copyFiles(URI[] uris, IContainer destination) {
+ IFileStore[] stores = buildFileStores(uris);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Copies the given files and folders to the destination without forking a
+ * new Thread or blocking using a WorkspaceModifyOperation. It is
+ * recommended that this method only be called from a {@link WorkspaceJob} to avoid possible deadlock.
+ *
+ * @param uris
+ * the URIs to copy
+ * @param destination
+ * destination to which URIS will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public void copyFilesInCurrentThread(URI[] uris, IContainer destination,
+ IProgressMonitor monitor) {
+ IFileStore[] stores = buildFileStores(uris);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, false, monitor);
+ }
+
+ /**
+ * Build the collection of fileStores that map to fileNames. If any of them
+ * cannot be found then match then return <code>null</code>.
+ *
+ * @param uris
+ * @return IFileStore[]
+ */
+ private IFileStore[] buildFileStores(URI[] uris) {
+ IFileStore[] stores = new IFileStore[uris.length];
+ for (int i = 0; i < uris.length; i++) {
+ IFileStore store;
+ try {
+ store = EFS.getStore(uris[i]);
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+ reportFileInfoNotFound(uris[i].toString());
+ return null;
+ }
+ if (store == null) {
+ reportFileInfoNotFound(uris[i].toString());
+ return null;
+ }
+ stores[i] = store;
+ }
+ return stores;
+
+ }
+
+ /**
+ * Depending on the 'Linked Resources' preferences it copies the given files and folders to the
+ * destination or creates links or shows a dialog that lets the user choose. The current thread
+ * is halted while the resources are copied using a {@link WorkspaceModifyOperation}. This
+ * method should be called from the UI Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @param dropOperation
+ * the drop operation ({@link DND#DROP_NONE}, {@link DND#DROP_MOVE} {@link DND#DROP_COPY}, {@link DND#DROP_LINK}, {@link DND#DROP_DEFAULT})
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void copyOrLinkFiles(final String[] fileNames, IContainer destination, int dropOperation) {
+ IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
+ boolean targetIsVirtual = destination.isVirtual();
+ String dndPreference = store.getString(targetIsVirtual ? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE : IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE);
+
+ int mode = ImportTypeDialog.IMPORT_NONE;
+ String variable = null;
+
+ // check if resource linking is disabled
+ if (ResourcesPlugin.getPlugin().getPluginPreferences().getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING)) {
+ mode = ImportTypeDialog.IMPORT_COPY;
+ } else {
+ if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT)) {
+ ImportTypeDialog dialog = new ImportTypeDialog(messageShell, dropOperation, fileNames, destination);
+ dialog.setResource(destination);
+ if (dialog.open() == Window.OK) {
+ mode = dialog.getSelection();
+ variable = dialog.getVariable();
+ }
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY)) {
+ mode = ImportTypeDialog.IMPORT_COPY;
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK)) {
+ mode = ImportTypeDialog.IMPORT_LINK;
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER)) {
+ mode = ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS;
+ }
+ }
+
+ switch (mode) {
+ case ImportTypeDialog.IMPORT_COPY:
+ copyFiles(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS:
+ if (variable != null) {
+ setRelativeVariable(variable);
+ }
+ createVirtualFoldersAndLinks(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_LINK:
+ if (variable != null) {
+ setRelativeVariable(variable);
+ }
+ linkFiles(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_NONE:
+ break;
+ }
+
+ }
+
+ /**
+ * Copies the given files and folders to the destination. The current Thread is halted while the
+ * resources are copied using a WorkspaceModifyOperation. This method should be called from the
+ * UI Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.2
+ */
+ public void copyFiles(final String[] fileNames, IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Copies the given files and folders to the destination without forking a
+ * new Thread or blocking using a WorkspaceModifyOperation. It is
+ * recommended that this method only be called from a {@link WorkspaceJob} to avoid possible deadlock.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public void copyFilesInCurrentThread(final String[] fileNames,
+ IContainer destination, IProgressMonitor monitor) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, false, monitor);
+ }
+
+ /**
+ * Build the collection of fileStores that map to fileNames. If any of them
+ * cannot be found then match then return null.
+ *
+ * @param fileNames
+ * @return IFileStore[]
+ */
+ private IFileStore[] buildFileStores(final String[] fileNames) {
+ IFileStore[] stores = new IFileStore[fileNames.length];
+ for (int i = 0; i < fileNames.length; i++) {
+ IFileStore store = IDEResourceInfoUtils.getFileStore(fileNames[i]);
+ if (store == null) {
+ reportFileInfoNotFound(fileNames[i]);
+ return null;
+ }
+ stores[i] = store;
+ }
+ return stores;
+ }
+
+ /**
+ * Report that a file info could not be found.
+ *
+ * @param fileName
+ */
+ private void reportFileInfoNotFound(final String fileName) {
+
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ ErrorDialog
+ .openError(
+ messageShell,
+ getProblemsTitle(),
+ NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
+ fileName), null);
+ }
+ });
+ }
+
+ /**
+ * Copies the given files and folders to the destination.
+ *
+ * @param stores
+ * the file stores to copy
+ * @param destination
+ * destination to which files will be copied
+ */
+ private void copyFileStores(IContainer destination,
+ final IFileStore[] stores, boolean fork, IProgressMonitor monitor) {
+ // test files for existence separate from validate API
+ // because an external file may not exist until the copy actually
+ // takes place (e.g., WinZip contents).
+ IStatus fileStatus = checkExist(stores);
+ if (fileStatus.getSeverity() != IStatus.OK) {
+ displayError(fileStatus);
+ return;
+ }
+ String errorMsg = validateImportDestinationInternal(destination, stores);
+ if (errorMsg != null) {
+ displayError(errorMsg);
+ return;
+ }
+ final IPath destinationPath = destination.getFullPath();
+
+ if (fork) {
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+ @Override
+ public void execute(IProgressMonitor monitor) {
+ copyFileStores(stores, destinationPath, monitor);
+ }
+ };
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(true, true,
+ op);
+ } catch (InterruptedException e) {
+ return;
+ } catch (InvocationTargetException exception) {
+ display(exception);
+ }
+ } else {
+ copyFileStores(stores, destinationPath, monitor);
+ }
+
+ // If errors occurred, open an Error dialog
+ if (errorStatus != null) {
+ displayError(errorStatus);
+ errorStatus = null;
+ }
+ }
+
+ /**
+ * Display the supplied status in an error dialog.
+ *
+ * @param status
+ * The status to display
+ */
+ protected void displayError(final IStatus status) {
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ ErrorDialog.openError(messageShell, getProblemsTitle(), null,
+ status);
+ }
+ });
+ }
+
+ /**
+ * Creates a file or folder handle for the source resource as if it were to
+ * be created in the destination container.
+ *
+ * @param destination
+ * destination container
+ * @param source
+ * source resource
+ * @return IResource file or folder handle, depending on the source type.
+ */
+ IResource createLinkedResourceHandle(IContainer destination,
+ IResource source) {
+ IWorkspace workspace = destination.getWorkspace();
+ IWorkspaceRoot workspaceRoot = workspace.getRoot();
+ IPath linkPath = destination.getFullPath().append(source.getName());
+ IResource linkHandle;
+
+ if (source.getType() == IResource.FOLDER) {
+ linkHandle = workspaceRoot.getFolder(linkPath);
+ } else {
+ linkHandle = workspaceRoot.getFile(linkPath);
+ }
+ return linkHandle;
+ }
+
+ /**
+ * Removes the given resource from the workspace.
+ *
+ * @param resource
+ * resource to remove from the workspace
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ * @return true the resource was deleted successfully false the resource was
+ * not deleted because a CoreException occurred
+ */
+ boolean delete(IResource resource, IProgressMonitor monitor) {
+ boolean force = false; // don't force deletion of out-of-sync resources
+
+ if (resource.getType() == IResource.PROJECT) {
+ // if it's a project, ask whether content should be deleted too
+ IProject project = (IProject) resource;
+ try {
+ project.delete(true, force, monitor);
+ } catch (CoreException e) {
+ recordError(e); // log error
+ return false;
+ }
+ } else {
+ // if it's not a project, just delete it
+ int flags = IResource.KEEP_HISTORY;
+ if (force) {
+ flags = flags | IResource.FORCE;
+ }
+ try {
+ resource.delete(flags, monitor);
+ } catch (CoreException e) {
+ recordError(e); // log error
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Opens an error dialog to display the given message.
+ *
+ * @param message
+ * the error message to show
+ */
+ protected void displayError(final String message) {
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ MessageDialog.openError(messageShell, getProblemsTitle(),
+ message);
+ }
+ });
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFile.
+ *
+ * @param resource
+ * resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFile. <code>null</code> if the resource does not adapt to IFile
+ */
+ protected IFile getFile(IResource resource) {
+ if (resource instanceof IFile) {
+ return (IFile) resource;
+ }
+ return (IFile) ((IAdaptable) resource).getAdapter(IFile.class);
+ }
+
+ /**
+ * Returns java.io.File objects for the given file names.
+ *
+ * @param fileNames
+ * files to return File object for.
+ * @return java.io.File objects for the given file names.
+ * @deprecated As of 3.3, this method is no longer in use anywhere in this
+ * class and is only provided for backwards compatability with
+ * subclasses of the receiver.
+ */
+ @Deprecated
+ protected File[] getFiles(String[] fileNames) {
+ File[] files = new File[fileNames.length];
+
+ for (int i = 0; i < fileNames.length; i++) {
+ files[i] = new File(fileNames[i]);
+ }
+ return files;
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFolder.
+ *
+ * @param resource
+ * resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFolder. <code>null</code> if the resource does not adapt to IFolder
+ */
+ protected IFolder getFolder(IResource resource) {
+ if (resource instanceof IFolder) {
+ return (IFolder) resource;
+ }
+ return (IFolder) ((IAdaptable) resource).getAdapter(IFolder.class);
+ }
+
+ /**
+ * Returns a new name for a copy of the resource at the given path in the
+ * given workspace.
+ *
+ * @param originalName
+ * the full path of the resource
+ * @param workspace
+ * the workspace
+ * @return the new full path for the copy, or <code>null</code> if the
+ * resource should not be copied
+ */
+ protected IPath getNewNameFor(final IPath originalName,
+ final IWorkspace workspace) {
+ final IResource resource = workspace.getRoot().findMember(originalName);
+ final IPath prefix = resource.getFullPath().removeLastSegments(1);
+ final String returnValue[] = { "" }; //$NON-NLS-1$
+
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ IInputValidator validator = new IInputValidator() {
+ public String isValid(String string) {
+ if (resource.getName().equals(string)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameMustBeDifferent;
+ }
+ IStatus status = workspace.validateName(string,
+ resource.getType());
+ if (!status.isOK()) {
+ return status.getMessage();
+ }
+ if (workspace.getRoot().exists(prefix.append(string))) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameExists;
+ }
+ return null;
+ }
+ };
+
+ InputDialog dialog = new InputDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogTitle,
+ NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogMessage,
+ resource.getName()), getAutoNewNameFor(
+ originalName, workspace).lastSegment()
+ .toString(), validator);
+ dialog.setBlockOnOpen(true);
+ dialog.open();
+ if (dialog.getReturnCode() == Window.CANCEL) {
+ returnValue[0] = null;
+ } else {
+ returnValue[0] = dialog.getValue();
+ }
+ }
+ });
+ if (returnValue[0] == null) {
+ throw new OperationCanceledException();
+ }
+ return prefix.append(returnValue[0]);
+ }
+
+ /**
+ * Returns the task title for this operation's progress dialog.
+ *
+ * @return the task title
+ */
+ protected String getOperationTitle() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_operationTitle;
+ }
+
+ /**
+ * Returns the message for this operation's problems dialog.
+ *
+ * @return the problems message
+ */
+ protected String getProblemsMessage() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_problemMessage;
+ }
+
+ /**
+ * Returns the title for this operation's problems dialog.
+ *
+ * @return the problems dialog title
+ */
+ protected String getProblemsTitle() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyFailedTitle;
+ }
+
+ /**
+ * Returns whether the source file in a destination collision will be
+ * validateEdited together with the collision itself. Returns false. Should
+ * return true if the source file is to be deleted after the operation.
+ *
+ * @return boolean <code>true</code> if the source file in a destination
+ * collision should be validateEdited. <code>false</code> if only
+ * the destination should be validated.
+ */
+ protected boolean getValidateConflictSource() {
+ return false;
+ }
+
+ /**
+ * Returns whether the given resources are either both linked or both
+ * unlinked.
+ *
+ * @param source
+ * source resource
+ * @param destination
+ * destination resource
+ * @return boolean <code>true</code> if both resources are either linked
+ * or unlinked. <code>false</code> otherwise.
+ */
+ protected boolean homogenousResources(IResource source,
+ IResource destination) {
+ boolean isSourceLinked = source.isLinked();
+ boolean isDestinationLinked = destination.isLinked();
+
+ return (isSourceLinked && isDestinationLinked || isSourceLinked == false
+ && isDestinationLinked == false);
+ }
+
+ /**
+ * Returns whether the given resource is accessible. Files and folders are
+ * always considered accessible and a project is accessible if it is open.
+ *
+ * @param resource
+ * the resource
+ * @return <code>true</code> if the resource is accessible, and <code>false</code> if it is not
+ */
+ private boolean isAccessible(IResource resource) {
+ switch (resource.getType()) {
+ case IResource.FILE:
+ return true;
+ case IResource.FOLDER:
+ return true;
+ case IResource.PROJECT:
+ return ((IProject) resource).isOpen();
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether any of the given source resources are being recopied to
+ * their current container.
+ *
+ * @param sourceResources
+ * the source resources
+ * @param destination
+ * the destination container
+ * @return <code>true</code> if at least one of the given source
+ * resource's parent container is the same as the destination
+ */
+ boolean isDestinationSameAsSource(IResource[] sourceResources,
+ IContainer destination) {
+ IPath destinationLocation = destination.getLocation();
+
+ for (int i = 0; i < sourceResources.length; i++) {
+ IResource sourceResource = sourceResources[i];
+ if (sourceResource.getParent().equals(destination)) {
+ return true;
+ } else if (destinationLocation != null) {
+ // do thorough check to catch linked resources. Fixes bug 29913.
+ IPath sourceLocation = sourceResource.getLocation();
+ IPath destinationResource = destinationLocation
+ .append(sourceResource.getName());
+ if (sourceLocation != null
+ && sourceLocation.isPrefixOf(destinationResource)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Copies the given resources to the destination container with the given
+ * name.
+ * <p>
+ * Note: the destination container may need to be created prior to copying the resources.
+ * </p>
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * the path of the destination container
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ * @return <code>true</code> if the copy operation completed without
+ * errors
+ */
+ protected boolean performCopy(IResource[] resources, IPath destination,
+ IProgressMonitor monitor) {
+ try {
+ AbstractWorkspaceOperation op = getUndoableCopyOrMoveOperation(
+ resources, destination);
+ op.setModelProviderIds(getModelProviderIds());
+ if (op instanceof CopyResourcesOperation) {
+ CopyResourcesOperation copyMoveOp = (CopyResourcesOperation) op;
+ copyMoveOp.setCreateVirtualFolders(createVirtualFoldersAndLinks);
+ copyMoveOp.setCreateLinks(createLinks);
+ copyMoveOp.setRelativeVariable(relativeVariable);
+ }
+ PlatformUI.getWorkbench().getOperationSupport()
+ .getOperationHistory().execute(op, monitor,
+ WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CoreException) {
+ recordError((CoreException) e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Individually copies the given resources to the specified destination
+ * container checking for name collisions. If a collision is detected, it is
+ * saved with a new name.
+ * <p>
+ * Note: the destination container may need to be created prior to copying the resources.
+ * </p>
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * the path of the destination container
+ * @return <code>true</code> if the copy operation completed without
+ * errors.
+ */
+ protected boolean performCopyWithAutoRename(IResource[] resources,
+ IPath destination, IProgressMonitor monitor) {
+ IWorkspace workspace = resources[0].getWorkspace();
+ IPath[] destinationPaths = new IPath[resources.length];
+ try {
+ for (int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ destinationPaths[i] = destination.append(source.getName());
+
+ if (workspace.getRoot().exists(destinationPaths[i])) {
+ destinationPaths[i] = getNewNameFor(destinationPaths[i],
+ workspace);
+ }
+ }
+ CopyResourcesOperation op = new CopyResourcesOperation(resources,
+ destinationPaths,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+ op.setModelProviderIds(getModelProviderIds());
+ PlatformUI.getWorkbench().getOperationSupport()
+ .getOperationHistory().execute(op, monitor,
+ WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CoreException) {
+ recordError((CoreException) e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Performs an import of the given stores into the provided container.
+ * Returns a status indicating if the import was successful.
+ *
+ * @param stores
+ * stores that are to be imported
+ * @param target
+ * container to which the import will be done
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ */
+ private void performFileImport(IFileStore[] stores, IContainer target,
+ IProgressMonitor monitor) {
+ IOverwriteQuery query = new IOverwriteQuery() {
+ public String queryOverwrite(String pathString) {
+ if (alwaysOverwrite) {
+ return ALL;
+ }
+
+ final String returnCode[] = { CANCEL };
+ final String msg = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteQuestion,
+ pathString);
+ final String[] options = { IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ MessageDialog dialog = new MessageDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_question,
+ null, msg, MessageDialog.QUESTION, options, 0) {
+ @Override
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ dialog.open();
+ int returnVal = dialog.getReturnCode();
+ String[] returnCodes = { YES, ALL, NO, CANCEL };
+ returnCode[0] = returnVal == -1 ? CANCEL
+ : returnCodes[returnVal];
+ }
+ });
+ if (returnCode[0] == ALL) {
+ alwaysOverwrite = true;
+ } else if (returnCode[0] == CANCEL) {
+ canceled = true;
+ }
+ return returnCode[0];
+ }
+ };
+
+ ImportOperation op = new ImportOperation(target.getFullPath(),
+ stores[0].getParent(), FileStoreStructureProvider.INSTANCE,
+ query, Arrays.asList(stores));
+ op.setContext(messageShell);
+ op.setCreateContainerStructure(false);
+ op.setVirtualFolders(createVirtualFoldersAndLinks);
+ op.setCreateLinks(createLinks);
+ op.setRelativeVariable(relativeVariable);
+ try {
+ op.run(monitor);
+ } catch (InterruptedException e) {
+ return;
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof CoreException) {
+ displayError(((CoreException) e.getTargetException())
+ .getStatus());
+ } else {
+ display(e);
+ }
+ return;
+ }
+ // Special case since ImportOperation doesn't throw a CoreException on
+ // failure.
+ IStatus status = op.getStatus();
+ if (!status.isOK()) {
+ if (errorStatus == null) {
+ errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.ERROR, getProblemsMessage(), null);
+ }
+ errorStatus.merge(status);
+ }
+ }
+
+ /**
+ * Records the core exception to be displayed to the user once the action is
+ * finished.
+ *
+ * @param error
+ * a <code>CoreException</code>
+ */
+ protected void recordError(CoreException error) {
+ if (errorStatus == null) {
+ errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.ERROR,
+ getProblemsMessage(), error);
+ }
+
+ errorStatus.merge(error.getStatus());
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source resources.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceResources
+ * the source resources
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ public String validateDestination(IContainer destination,
+ IResource[] sourceResources) {
+ if (!isAccessible(destination)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
+ }
+ IContainer firstParent = null;
+ URI destinationLocation = destination.getLocationURI();
+ for (int i = 0; i < sourceResources.length; i++) {
+ IResource sourceResource = sourceResources[i];
+ if (firstParent == null) {
+ firstParent = sourceResource.getParent();
+ } else if (firstParent.equals(sourceResource.getParent()) == false) {
+ // Resources must have common parent. Fixes bug 33398.
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_parentNotEqual;
+ }
+
+ // verify that if the destination is a virtual folder, the resource must be
+ // either a link or another virtual folder
+ if (destination.isVirtual()) {
+ if (!sourceResource.isLinked() && !sourceResource.isVirtual()
+ && !createLinks && !createVirtualFoldersAndLinks) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sourceCannotBeCopiedIntoAVirtualFolder,
+ sourceResource.getName());
+ }
+ }
+ URI sourceLocation = sourceResource.getLocationURI();
+ if (sourceLocation == null) {
+ if (sourceResource.isLinked()) {
+ // Don't allow copying linked resources with undefined path
+ // variables. See bug 28754.
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable,
+ sourceResource.getName());
+ }
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ sourceResource.getName());
+
+ }
+ if (!destination.isVirtual()) {
+ if (sourceLocation.equals(destinationLocation)) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
+ sourceResource.getName());
+ }
+ // is the source a parent of the destination?
+ if (new Path(sourceLocation.toString()).isPrefixOf(new Path(
+ destinationLocation.toString()))) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
+ }
+ }
+
+ String linkedResourceMessage = validateLinkedResource(destination,
+ sourceResource);
+ if (linkedResourceMessage != null) {
+ return linkedResourceMessage;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Validates that the given source resources can be copied to the
+ * destination as decided by the VCM provider.
+ *
+ * @param destination
+ * copy destination
+ * @param sourceResources
+ * source resources
+ * @return <code>true</code> all files passed validation or there were no
+ * files to validate. <code>false</code> one or more files did not
+ * pass validation.
+ */
+ private boolean validateEdit(IContainer destination,
+ IResource[] sourceResources) {
+ ArrayList copyFiles = new ArrayList();
+
+ collectExistingReadonlyFiles(destination.getFullPath(),
+ sourceResources, copyFiles);
+ if (copyFiles.size() > 0) {
+ IFile[] files = (IFile[]) copyFiles.toArray(new IFile[copyFiles
+ .size()]);
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IStatus status = workspace.validateEdit(files, messageShell);
+
+ canceled = status.isOK() == false;
+ return status.isOK();
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source files.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceNames
+ * the source file names
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ public String validateImportDestination(IContainer destination,
+ String[] sourceNames) {
+
+ IFileStore[] stores = new IFileStore[sourceNames.length];
+ for (int i = 0; i < sourceNames.length; i++) {
+ IFileStore store = IDEResourceInfoUtils
+ .getFileStore(sourceNames[i]);
+ if (store == null) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
+ sourceNames[i]);
+ }
+ stores[i] = store;
+ }
+ return validateImportDestinationInternal(destination, stores);
+
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source file
+ * stores.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ * <p>
+ * TODO Bug 117804. This method has been renamed to avoid a bug in the Eclipse compiler with regards to visibility and type resolution when linking.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceStores
+ * the source IFileStore
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ private String validateImportDestinationInternal(IContainer destination,
+ IFileStore[] sourceStores) {
+ if (!isAccessible(destination)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
+ }
+
+ if (!destination.isVirtual()) {
+ IFileStore destinationStore;
+ try {
+ destinationStore = EFS.getStore(destination.getLocationURI());
+ } catch (CoreException exception) {
+ IDEWorkbenchPlugin.log(exception.getLocalizedMessage(), exception);
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ exception.getLocalizedMessage());
+ }
+ for (int i = 0; i < sourceStores.length; i++) {
+ IFileStore sourceStore = sourceStores[i];
+ IFileStore sourceParentStore = sourceStore.getParent();
+
+ if (sourceStore != null) {
+ if (destinationStore.equals(sourceStore)
+ || (sourceParentStore != null && destinationStore
+ .equals(sourceParentStore))) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_importSameSourceAndDest,
+ sourceStore.getName());
+ }
+ // work around bug 16202. replacement for
+ // sourcePath.isPrefixOf(destinationPath)
+ if (sourceStore.isParentOf(destinationStore)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Check if the destination is valid for the given source resource.
+ *
+ * @param destination
+ * destination container of the operation
+ * @param source
+ * source resource
+ * @return String error message or null if the destination is valid
+ */
+ private String validateLinkedResource(IContainer destination,
+ IResource source) {
+ if ((source.isLinked() == false) || source.isVirtual()) {
+ return null;
+ }
+ IWorkspace workspace = destination.getWorkspace();
+ IResource linkHandle = createLinkedResourceHandle(destination, source);
+ IStatus locationStatus = workspace.validateLinkLocationURI(linkHandle,
+ source.getRawLocationURI());
+
+ if (locationStatus.getSeverity() == IStatus.ERROR) {
+ return locationStatus.getMessage();
+ }
+ IPath sourceLocation = source.getLocation();
+ if (source.getProject().equals(destination.getProject()) == false
+ && source.getType() == IResource.FOLDER
+ && sourceLocation != null) {
+ // prevent merging linked folders that point to the same
+ // file system folder
+ try {
+ IResource[] members = destination.members();
+ for (int j = 0; j < members.length; j++) {
+ if (sourceLocation.equals(members[j].getLocation())
+ && source.getName().equals(members[j].getName())) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
+ source.getName());
+ }
+ }
+ } catch (CoreException exception) {
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ exception.getMessage()));
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether moving all of the given source resources to the given
+ * destination container could be done without causing name collisions.
+ *
+ * @param destination
+ * the destination container
+ * @param sourceResources
+ * the list of resources
+ * @return <code>true</code> if there would be no name collisions, and <code>false</code> if there would
+ */
+ private IResource[] validateNoNameCollisions(IContainer destination,
+ IResource[] sourceResources) {
+ List copyItems = new ArrayList();
+ IWorkspaceRoot workspaceRoot = destination.getWorkspace().getRoot();
+ int overwrite = IDialogConstants.NO_ID;
+
+ // Check to see if we would be overwriting a parent folder.
+ // Cancel entire copy operation if we do.
+ for (int i = 0; i < sourceResources.length; i++) {
+ final IResource sourceResource = sourceResources[i];
+ final IPath destinationPath = destination.getFullPath().append(
+ sourceResource.getName());
+ final IPath sourcePath = sourceResource.getFullPath();
+
+ IResource newResource = workspaceRoot.findMember(destinationPath);
+ if (newResource != null && destinationPath.isPrefixOf(sourcePath)) {
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteProblem,
+ destinationPath, sourcePath));
+
+ canceled = true;
+ return null;
+ }
+ }
+ // Check for overwrite conflicts
+ for (int i = 0; i < sourceResources.length; i++) {
+ final IResource source = sourceResources[i];
+ final IPath destinationPath = destination.getFullPath().append(
+ source.getName());
+
+ IResource newResource = workspaceRoot.findMember(destinationPath);
+ if (newResource != null) {
+ if (overwrite != IDialogConstants.YES_TO_ALL_ID
+ || (newResource.getType() == IResource.FOLDER && homogenousResources(
+ source, destination) == false)) {
+ overwrite = checkOverwrite(source, newResource);
+ }
+ if (overwrite == IDialogConstants.YES_ID
+ || overwrite == IDialogConstants.YES_TO_ALL_ID) {
+ copyItems.add(source);
+ } else if (overwrite == IDialogConstants.CANCEL_ID) {
+ canceled = true;
+ return null;
+ }
+ } else {
+ copyItems.add(source);
+ }
+ }
+ return (IResource[]) copyItems.toArray(new IResource[copyItems.size()]);
+ }
+
+ private void copyResources(final IResource[] resources,
+ final IPath destinationPath, final IResource[][] copiedResources,
+ IProgressMonitor monitor) {
+ IResource[] copyResources = resources;
+
+ // Fix for bug 31116. Do not provide a task name when
+ // creating the task.
+ monitor.beginTask("", 100); //$NON-NLS-1$
+ monitor.setTaskName(getOperationTitle());
+ monitor.worked(10); // show some initial progress
+
+ // Checks only required if this is an exisiting container path.
+ boolean copyWithAutoRename = false;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (root.exists(destinationPath)) {
+ IContainer container = (IContainer) root
+ .findMember(destinationPath);
+ // If we're copying to the source container then perform
+ // auto-renames on all resources to avoid name collisions.
+ if (isDestinationSameAsSource(copyResources, container)
+ && canPerformAutoRename()) {
+ copyWithAutoRename = true;
+ } else {
+ // If no auto-renaming will be happening, check for
+ // potential name collisions at the target resource
+ copyResources = validateNoNameCollisions(container,
+ copyResources);
+ if (copyResources == null) {
+ if (canceled) {
+ return;
+ }
+ displayError(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameCollision);
+ return;
+ }
+ if (validateEdit(container, copyResources) == false) {
+ return;
+ }
+ }
+ }
+
+ errorStatus = null;
+ if (copyResources.length > 0) {
+ if (copyWithAutoRename) {
+ performCopyWithAutoRename(copyResources, destinationPath,
+ new SubProgressMonitor(monitor, 90));
+ } else {
+ performCopy(copyResources, destinationPath, new SubProgressMonitor(monitor, 90));
+ }
+ }
+ monitor.done();
+ copiedResources[0] = copyResources;
+ }
+
+ private void copyFileStores(final IFileStore[] stores,
+ final IPath destinationPath, IProgressMonitor monitor) {
+ // Checks only required if this is an exisiting container path.
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (root.exists(destinationPath)) {
+ IContainer container = (IContainer) root
+ .findMember(destinationPath);
+
+ performFileImport(stores, container, monitor);
+ }
+ }
+
+ /**
+ * Returns the model provider ids that are known to the client that
+ * instantiated this operation.
+ *
+ * @return the model provider ids that are known to the client that
+ * instantiated this operation.
+ * @since 3.2
+ */
+ public String[] getModelProviderIds() {
+ return modelProviderIds;
+ }
+
+ /**
+ * Sets the model provider ids that are known to the client that
+ * instantiated this operation. Any potential side effects reported by these
+ * models during validation will be ignored.
+ *
+ * @param modelProviderIds
+ * the model providers known to the client who is using this
+ * operation.
+ * @since 3.2
+ */
+ public void setModelProviderIds(String[] modelProviderIds) {
+ this.modelProviderIds = modelProviderIds;
+ }
+
+ /**
+ * Create virtual folders and links of the given files and folders to the
+ * destination. The current Thread is halted while the resources are copied
+ * using a WorkspaceModifyOperation. This method should be called from the
+ * UI Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void createVirtualFoldersAndLinks(final String[] fileNames,
+ IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ createVirtualFoldersAndLinks = true;
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Create links of the given files and folders to the destination. The
+ * current Thread is halted while the resources are copied using a
+ * WorkspaceModifyOperation. This method should be called from the UI
+ * Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void linkFiles(final String[] fileNames, IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ createLinks = true;
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Set whether or not virtual folders and links will be created under the destination
+ * container.
+ *
+ * @param value
+ * @since 3.6
+ */
+ public void setVirtualFolders(boolean value) {
+ createVirtualFoldersAndLinks = value;
+ }
+
+ /**
+ * Set whether or not links will be created under the destination container.
+ *
+ * @param value
+ * @since 3.6
+ */
+ public void setCreateLinks(boolean value) {
+ createLinks = value;
+ }
+
+ /**
+ * Set a variable relative to which the links are created
+ *
+ * @param variable
+ * @since 3.6
+ */
+ public void setRelativeVariable(String variable) {
+ relativeVariable = variable;
+ }
+
+ /**
+ * Returns an AbstractWorkspaceOperation suitable for performing the move or
+ * copy operation that will move or copy the given resources to the given
+ * destination path.
+ *
+ * @param resources
+ * the resources to be moved or copied
+ * @param destinationPath
+ * the destination path to which the resources should be moved
+ * @return the operation that should be used to perform the move or cop
+ * @since 3.3
+ */
+ protected AbstractWorkspaceOperation getUndoableCopyOrMoveOperation(
+ IResource[] resources, IPath destinationPath) {
+ return new CopyResourcesOperation(resources, destinationPath,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusCopyFilesAndFoldersOperation.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusCopyFilesAndFoldersOperation.java
new file mode 100644
index 00000000000..05e987f060b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusCopyFilesAndFoldersOperation.java
@@ -0,0 +1,265 @@
+/*****************************************************************************
+ * 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:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.action;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.infra.core.resource.ModelMultiException;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.core.utils.DiResourceSet;
+import org.eclipse.papyrus.infra.emf.resource.DependencyManagementHelper;
+import org.eclipse.papyrus.infra.emf.resource.MoveFileURIReplacementStrategy;
+import org.eclipse.papyrus.infra.emf.resource.RestoreDependencyHelper;
+import org.eclipse.papyrus.infra.emf.utils.ResourceUtils;
+import org.eclipse.papyrus.infra.onefile.internal.ui.Activator;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.undo.CopyResourcesOperation;
+import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+
+
+/**
+ * Implementation of Papyrus paste for model
+ */
+public class PapyrusCopyFilesAndFoldersOperation extends CopyFilesAndFoldersOperation {
+
+ protected Map<String, String> renameMapping = new HashMap<String, String>();
+
+ protected IPath[] destinationPaths = null;
+
+ public PapyrusCopyFilesAndFoldersOperation(Shell shell) {
+ super(shell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#performCopyWithAutoRename(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ // perform rename only for .di
+ protected boolean performCopyWithAutoRename(IResource[] resources, IPath destination, IProgressMonitor monitor) {
+ IWorkspace workspace = resources[0].getWorkspace();
+ destinationPaths = new IPath[resources.length];
+ try {
+ String oldName = ""; //$NON-NLS-1$
+ String newName = ""; //$NON-NLS-1$
+ for (int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ destinationPaths[i] = destination.append(source.getName());
+ IPath relativSourcePath = source.getFullPath();
+ String sourceFileName = relativSourcePath.removeFileExtension().lastSegment();
+ if (sourceFileName.equals(oldName)) {
+ String fileExtension = relativSourcePath.getFileExtension();
+ destinationPaths[i] = relativSourcePath.removeLastSegments(1).append(newName).addFileExtension(fileExtension);
+ } else {
+ oldName = sourceFileName;
+ if (workspace.getRoot().exists(destinationPaths[i]) && destinationPaths[i].getFileExtension().equals(DiModel.MODEL_FILE_EXTENSION)) {
+ destinationPaths[i] = getNewNameFor(destinationPaths[i], workspace);
+ newName = destinationPaths[i].removeFileExtension().lastSegment();
+ }
+ renameMapping.put(oldName, newName);
+ }
+
+ }
+ CopyResourcesOperation op = new CopyResourcesOperation(resources, destinationPaths, IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+ op.setModelProviderIds(getModelProviderIds());
+ PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().execute(op, monitor, WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CoreException) {
+ recordError((CoreException) e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#performCopy(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ // store path of created files
+ protected boolean performCopy(IResource[] resources, IPath destination, IProgressMonitor monitor) {
+ boolean performCopy = super.performCopy(resources, destination, monitor);
+ if (performCopy) {
+ destinationPaths = new IPath[resources.length];
+ for (int i = 0; i < resources.length; i++) {
+ String name = resources[i].getName();
+ destinationPaths[i] = destination.append(name);
+ }
+ }
+ return performCopy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#copyResources(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.resources.IContainer)
+ */
+ @Override
+ // restore internal and external link coherence
+ public IResource[] copyResources(IResource[] resources, IContainer destination) {
+ IResource[] copyResources = super.copyResources(resources, destination);
+ try {
+ List<ModelSet> modelSetList = initModelSet(copyResources);
+ Map<URI, URI> constructInternalMapping = constructInternalMapping(copyResources);
+ for (int i = 0; i < resources.length; i++) {
+ for (ModelSet modelSet : modelSetList) {
+ if (checkResource(modelSet, resources[i])) {
+ restoreAllLink(modelSet, constructInternalMapping, copyResources[i], destinationPaths[i]);
+ }
+ }
+ }
+ } catch (IOException e) {
+ Activator.log.error("It was not possible to restore broken links", e); //$NON-NLS-1$
+ }
+ return copyResources;
+ }
+
+ /**
+ * Init a modelSet with registred model from resources
+ *
+ * @param resources
+ * @return
+ */
+ protected List<ModelSet> initModelSet(IResource[] resources) {
+ List<ModelSet> modelSetList = new ArrayList<ModelSet>();
+ for (IResource iResource : resources) {
+ IPath fullPath = iResource.getFullPath();
+ if (DiModel.MODEL_FILE_EXTENSION.equals(fullPath.getFileExtension())) {
+ if (iResource instanceof IFile) {
+ try {
+ ModelSet modelSet = new DiResourceSet();
+ modelSet.loadModels((IFile) iResource);
+ modelSetList.add(modelSet);
+ } catch (ModelMultiException e) {
+ Activator.log.error("It was not possible to load models", e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return modelSetList;
+ }
+
+ /**
+ * Check if the iResource is known by the ModelSet
+ *
+ * @param modelSet
+ * @param iResource
+ * @return
+ */
+ protected boolean checkResource(ModelSet modelSet, IResource iResource) {
+ URI uri = URI.createPlatformResourceURI(iResource.getFullPath().toString(), Boolean.TRUE);
+ Resource resource = modelSet.getResource(uri, Boolean.FALSE);
+ return resource != null;
+ }
+
+ /**
+ * Restore referenced URI following the pattern ;
+ * - if there is an accessible Resource use it
+ * - else search the resource in the source location of the copy
+ *
+ * Restore links to maintain coherence in the 3 files: uml-notation-di
+ *
+ * @param modelSet
+ * @param constructInternalMapping
+ * @param copyResources
+ * @param targetPath
+ * @throws IOException
+ */
+ protected void restoreAllLink(ModelSet modelSet, Map<URI, URI> constructInternalMapping, IResource copyResources, IPath targetPath) throws IOException {
+ URI uri = URI.createPlatformResourceURI(targetPath.toString(), Boolean.TRUE);
+ Resource resource = modelSet.getResource(uri, Boolean.TRUE);
+
+ // restore external links
+ MoveFileURIReplacementStrategy iURIReplacementStrategy = new MoveFileURIReplacementStrategy(new HashMap<URI, URI>(), copyResources.getFullPath().removeLastSegments(1), targetPath.removeLastSegments(1));
+ RestoreDependencyHelper restoreDependencyHelper = new RestoreDependencyHelper(iURIReplacementStrategy);
+ restoreDependencyHelper.restoreDependencies(resource);
+
+ // restore internal links
+ for (Entry<URI, URI> oneInternalCopyMapping : constructInternalMapping.entrySet()) {
+ DependencyManagementHelper.updateDependencies(oneInternalCopyMapping.getKey(), oneInternalCopyMapping.getValue(), resource);
+ }
+ resource.save(ResourceUtils.getSaveOptions());
+ IPath fullPath = copyResources.getFullPath();
+ Resource sashResource = null;
+
+ // restore links for sash
+ if (DiModel.MODEL_FILE_EXTENSION.equals(fullPath.getFileExtension())) {
+ SashModel sashModel = SashModelUtils.getSashModel(modelSet);
+ if (sashModel != null && !constructInternalMapping.containsKey(sashModel.getURI())) { // Kepler and earlier stored the sash model in the DI
+ sashResource = sashModel.getResource();
+ for (Entry<URI, URI> oneInternalCopyMapping : constructInternalMapping.entrySet()) {
+ DependencyManagementHelper.updateDependencies(oneInternalCopyMapping.getKey(), oneInternalCopyMapping.getValue(), sashResource);
+ }
+ }
+ if (sashResource != null) { // save new sash model
+ ModelSet tempModelSet = new DiResourceSet();
+ tempModelSet.createModels(uri);
+ URI newsashModelURI = SashModelUtils.getSashModel(tempModelSet).getURI();
+ sashResource.setURI(newsashModelURI);
+ sashResource.save(ResourceUtils.getSaveOptions());
+ }
+ }
+ }
+
+ /**
+ * Construct an URI mapping from source to target
+ *
+ * @param copyResources
+ * @return
+ */
+ protected Map<URI, URI> constructInternalMapping(IResource[] copyResources) {
+ Map<URI, URI> internalCopyMapping = new HashMap<URI, URI>();
+ for (int j = 0; j < copyResources.length; j++) {
+ IPath targetPath = destinationPaths[j];
+ IResource sourceResource = copyResources[j];
+ URI targetURI = URI.createPlatformResourceURI(targetPath.toString(), true);
+ URI sourceURI = URI.createPlatformResourceURI(sourceResource.getFullPath().toString(), true);
+ internalCopyMapping.put(sourceURI, targetURI);
+ }
+ return internalCopyMapping;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusModelPasteAction.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusModelPasteAction.java
new file mode 100644
index 00000000000..1b06a92d01f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PapyrusModelPasteAction.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * 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:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.action;
+
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * Action for pasting IPapyrusfiles
+ *
+ */
+public class PapyrusModelPasteAction extends PasteAction {
+
+
+ /**
+ * Action for pasting IPapyrusfiles
+ *
+ * @param shell
+ * @param clipboard
+ */
+ public PapyrusModelPasteAction(Shell shell, Clipboard clipboard) {
+ super(shell, clipboard);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.PasteAction#createCopyFilesAndFolderOperation(org.eclipse.swt.widgets.Shell)
+ */
+ @Override
+ protected CopyFilesAndFoldersOperation createCopyFilesAndFolderOperation(Shell shell) {
+ return new PapyrusCopyFilesAndFoldersOperation(shell);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PasteAction.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PasteAction.java
new file mode 100644
index 00000000000..4ca3a656edf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/action/PasteAction.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.action;
+
+
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyProjectOperation;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for pasting resources on the clipboard to the selected resource's location.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 2.0
+ */
+/* package */class PasteAction extends SelectionListenerAction {
+
+ /**
+ * The id of this action.
+ */
+ public static final String ID = PlatformUI.PLUGIN_ID + ".PasteAction";//$NON-NLS-1$
+
+ /**
+ * The shell in which to show any dialogs.
+ */
+ protected Shell shell;
+
+ /**
+ * System clipboard
+ */
+ protected Clipboard clipboard;
+
+ /**
+ * Creates a new action.
+ *
+ * @param shell
+ * the shell for any dialogs
+ * @param clipboard
+ * the clipboard
+ */
+ public PasteAction(Shell shell, Clipboard clipboard) {
+ super(WorkbenchNavigatorMessages.PasteAction_Past_);
+ Assert.isNotNull(shell);
+ Assert.isNotNull(clipboard);
+ this.shell = shell;
+ this.clipboard = clipboard;
+ setToolTipText(WorkbenchNavigatorMessages.PasteAction_Paste_selected_resource_s_);
+ setId(PasteAction.ID);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this, "HelpId"); //$NON-NLS-1$
+ // TODO INavigatorHelpContextIds.PASTE_ACTION);
+ }
+
+ /**
+ * Returns the actual target of the paste action. Returns null
+ * if no valid target is selected.
+ *
+ * @return the actual target of the paste action
+ */
+ private IResource getTarget() {
+ List<? extends IResource> selectedResources = getSelectedResources();
+
+ for (IResource resource : selectedResources) {
+ if (resource instanceof IProject && !((IProject) resource).isOpen()) {
+ return null;
+ }
+ if (resource.getType() == IResource.FILE) {
+ resource = resource.getParent();
+ }
+ if (resource != null) {
+ return resource;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether any of the given resources are linked resources.
+ *
+ * @param resources
+ * resource to check for linked type. may be null
+ * @return true=one or more resources are linked. false=none of the
+ * resources are linked
+ */
+ private boolean isLinked(IResource[] resources) {
+ for (int i = 0; i < resources.length; i++) {
+ if (resources[i].isLinked()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Implementation of method defined on <code>IAction</code>.
+ */
+ @Override
+ public void run() {
+ // try a resource transfer
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ IResource[] resourceData = (IResource[]) clipboard
+ .getContents(resTransfer);
+
+ if (resourceData != null && resourceData.length > 0) {
+ if (resourceData[0].getType() == IResource.PROJECT) {
+ // enablement checks for all projects
+ for (int i = 0; i < resourceData.length; i++) {
+ CopyProjectOperation operation = new CopyProjectOperation(
+ this.shell);
+ operation.copyProject((IProject) resourceData[i]);
+ }
+ } else {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = createCopyFilesAndFolderOperation(this.shell);
+ operation.copyResources(resourceData, container);
+ }
+ return;
+ }
+
+ // try a file transfer
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ String[] fileData = (String[]) clipboard.getContents(fileTransfer);
+
+ if (fileData != null) {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = createCopyFilesAndFolderOperation(this.shell);
+ operation.copyFiles(fileData, container);
+ }
+ }
+
+ protected CopyFilesAndFoldersOperation createCopyFilesAndFolderOperation(Shell shell) {
+ return new CopyFilesAndFoldersOperation(shell);
+ }
+
+
+
+
+ /**
+ * Returns the container to hold the pasted resources.
+ */
+ protected IContainer getContainer() {
+ List<? extends IResource> selection = getSelectedResources();
+ if (selection.get(0) instanceof IFile) {
+ return ((IFile) selection.get(0)).getParent();
+ }
+ return (IContainer) selection.get(0);
+ }
+
+ /**
+ * The <code>PasteAction</code> implementation of this <code>SelectionListenerAction</code> method enables this action if
+ * a resource compatible with what is on the clipboard is selected.
+ *
+ * -Clipboard must have IResource or java.io.File
+ * -Projects can always be pasted if they are open
+ * -Workspace folder may not be copied into itself
+ * -Files and folders may be pasted to a single selected folder in open
+ * project or multiple selected files in the same folder
+ */
+ @Override
+ protected boolean updateSelection(IStructuredSelection selection) {
+ if (!super.updateSelection(selection)) {
+ return false;
+ }
+
+ final IResource[][] clipboardData = new IResource[1][];
+ shell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ // clipboard must have resources or files
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ clipboardData[0] = (IResource[]) clipboard
+ .getContents(resTransfer);
+ }
+ });
+ IResource[] resourceData = clipboardData[0];
+ boolean isProjectRes = resourceData != null && resourceData.length > 0
+ && resourceData[0].getType() == IResource.PROJECT;
+
+ if (isProjectRes) {
+ for (int i = 0; i < resourceData.length; i++) {
+ // make sure all resource data are open projects
+ // can paste open projects regardless of selection
+ if (resourceData[i].getType() != IResource.PROJECT
+ || ((IProject) resourceData[i]).isOpen() == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (getSelectedNonResources().size() > 0) {
+ return false;
+ }
+
+ IResource targetResource = getTarget();
+ // targetResource is null if no valid target is selected (e.g., open project)
+ // or selection is empty
+ if (targetResource == null) {
+ return false;
+ }
+
+ // can paste files and folders to a single selection (file, folder,
+ // open project) or multiple file selection with the same parent
+ List<? extends IResource> selectedResources = getSelectedResources();
+ if (selectedResources.size() > 1) {
+ for (IResource resource : selectedResources) {
+ if (resource.getType() != IResource.FILE) {
+ return false;
+ }
+ if (!targetResource.equals(resource.getParent())) {
+ return false;
+ }
+ }
+ }
+ if (resourceData != null) {
+ // linked resources can only be pasted into projects
+ if (isLinked(resourceData)
+ && targetResource.getType() != IResource.PROJECT
+ && targetResource.getType() != IResource.FOLDER) {
+ return false;
+ }
+
+ if (targetResource.getType() == IResource.FOLDER) {
+ // don't try to copy folder to self
+ for (int i = 0; i < resourceData.length; i++) {
+ if (targetResource.equals(resourceData[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ TransferData[] transfers = clipboard.getAvailableTypes();
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ for (int i = 0; i < transfers.length; i++) {
+ if (fileTransfer.isSupportedType(transfers[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/filters/OnlyDiFilter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/filters/OnlyDiFilter.java
new file mode 100644
index 00000000000..bd64925dbaf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/filters/OnlyDiFilter.java
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.filters;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils;
+
+/**
+ * Filter hiding di files and associated. the filter enables the content
+ * provider
+ *
+ * @author tfaure
+ *
+ */
+public class OnlyDiFilter extends ViewerFilter {
+
+ public static final String FILTER_ID = "org.eclipse.papyrus.infra.onefile.onlyDiFilter";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers
+ * .Viewer, java.lang.Object, java.lang.Object)
+ *
+ * @Override
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ return OneFileUtils.isVisible(element);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ViewerFilter#isFilterProperty(java.lang.Object,
+ * java.lang.String)
+ *
+ * @Override
+ */
+ @Override
+ public boolean isFilterProperty(Object element, String property) {
+ return true;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/ModelAdapterFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/ModelAdapterFactory.java
new file mode 100644
index 00000000000..223ff8c4e6a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/ModelAdapterFactory.java
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 Atos Origin Integration, 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.ui.IContributorResourceAdapter;
+import org.eclipse.ui.ide.IContributorResourceAdapter2;
+
+/**
+ * Adapter factory to adapt {@link IPapyrusFile}
+ *
+ * @author tristan.faure@atosorigin.com
+ */
+public class ModelAdapterFactory implements IAdapterFactory {
+
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (IContributorResourceAdapter.class.equals(adapterType)) {
+ return adapterType.cast(new PapyrusModelContributorResourceAdapter());
+ }
+ if (IContributorResourceAdapter2.class.equals(adapterType)) {
+ return adapterType.cast(new PapyrusModelContributorResourceAdapter());
+ }
+ return null;
+ }
+
+ public Class<?>[] getAdapterList() {
+ return new Class[] { IContributorResourceAdapter.class, IContributorResourceAdapter2.class };
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusCommonDropAdapterAssistant.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusCommonDropAdapterAssistant.java
new file mode 100644
index 00000000000..e7e8bd4f18f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusCommonDropAdapterAssistant.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration - 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.ui.navigator.CommonDropAdapter;
+import org.eclipse.ui.navigator.resources.ResourceDropAdapterAssistant;
+
+/**
+ * Assistant to manage drag and drop of {@link IPapyrusFile} {@link IPapyrusFile} are not adapted to {@link IResource} to prevent
+ * misunderstanding so during transfer the selection is changed
+ *
+ * @author tristan.faure@atosorigin.com
+ *
+ */
+public class PapyrusCommonDropAdapterAssistant extends ResourceDropAdapterAssistant {
+
+ @Override
+ public IStatus validateDrop(Object target, int aDropOperation, TransferData transferType) {
+ manageSelection();
+ return super.validateDrop(target, aDropOperation, transferType);
+ }
+
+ @Override
+ public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) {
+ manageSelection();
+ return super.handleDrop(aDropAdapter, aDropTargetEvent, aTarget);
+ }
+
+ @Override
+ protected void doInit() {
+ super.doInit();
+ manageSelection();
+ }
+
+ private void manageSelection() {
+ List<Object> elements = new ArrayList<Object>();
+ ISelection selec = LocalSelectionTransfer.getTransfer().getSelection();
+ boolean selectionChanged = false;
+ if (selec instanceof IStructuredSelection) {
+ IStructuredSelection struc = (IStructuredSelection) selec;
+ for (Iterator<Object> i = struc.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IPapyrusFile) {
+ IPapyrusFile papy = (IPapyrusFile) o;
+ // TODO if a drop assistant is implemented use previous implementation :
+ // elements.add(papy.getMainFile());
+ elements.addAll(Arrays.asList(papy.getAssociatedResources()));
+ selectionChanged = true;
+ } else {
+ elements.add(o); // Do not prevent other drops.
+ }
+ }
+ }
+
+ if (!selectionChanged) {
+ return;
+ }
+
+ LocalSelectionTransfer.getTransfer().setSelection(new StructuredSelection(elements));
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusLinkHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusLinkHelper.java
new file mode 100644
index 00000000000..76e629c7563
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusLinkHelper.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.papyrus.infra.onefile.model.PapyrusModelHelper;
+import org.eclipse.papyrus.infra.onefile.ui.utils.OneFileUIUtils;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.navigator.ILinkHelper;
+
+/**
+ * Link the Papyrus Editor with {@link IPapyrusFile}
+ *
+ * @author tristan.faure@atosorigin.com
+ *
+ */
+public class PapyrusLinkHelper implements ILinkHelper {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.navigator.ILinkHelper#findSelection(org.eclipse.ui.
+ * IEditorInput)
+ */
+ public IStructuredSelection findSelection(IEditorInput anInput) {
+ List<Object> select = new ArrayList<Object>();
+ if (anInput instanceof IFileEditorInput) {
+ IFileEditorInput input = (IFileEditorInput) anInput;
+ IPapyrusFile papy = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(input.getFile());
+ select.add(papy);
+ IResource res = papy.getMainFile();
+ while (res.getParent() != null) {
+ select.add(0, res.getParent());
+ res = res.getParent();
+ }
+ return new StructuredSelection(papy);
+ }
+ return null;
+ }
+
+ public void activateEditor(IWorkbenchPage page, IStructuredSelection selection) {
+ if (selection == null || selection.isEmpty()) {
+ return;
+ }
+ Object element = selection.getFirstElement();
+ IEditorPart part = OneFileUIUtils.isOpenInEditor(element);
+ if (part != null) {
+ page.bringToTop(part);
+ }
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusModelContributorResourceAdapter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusModelContributorResourceAdapter.java
new file mode 100644
index 00000000000..cb48e6f8fae
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/PapyrusModelContributorResourceAdapter.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atos.net - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.ide.IContributorResourceAdapter2;
+
+
+/**
+ * Another Adapter
+ *
+ * @author tfaure
+ *
+ */
+public class PapyrusModelContributorResourceAdapter implements IContributorResourceAdapter2 {
+
+ public IResource getAdaptedResource(IAdaptable adaptable) {
+ IResource res = (IResource) adaptable.getAdapter(IResource.class);
+ return res;
+ }
+
+ public ResourceMapping getAdaptedResourceMapping(IAdaptable adaptable) {
+ ResourceMapping res = (ResourceMapping) adaptable.getAdapter(ResourceMapping.class);
+ return res;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/SubResourceAdapterFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/SubResourceAdapterFactory.java
new file mode 100644
index 00000000000..e68c86ffc5b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/model/adapters/SubResourceAdapterFactory.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 Atos Origin Integration, 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.model.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.papyrus.infra.onefile.model.ISubResourceFile;
+import org.eclipse.ui.IContributorResourceAdapter;
+
+/**
+ * Adapter Factory for {@link ISubResourceFile}
+ *
+ * @author tristan.faure@atosorigin.com
+ *
+ */
+public class SubResourceAdapterFactory implements IAdapterFactory {
+
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (IContributorResourceAdapter.class.equals(adapterType)) {
+ if (adaptableObject instanceof ISubResourceFile) {
+ return adapterType.cast(new PapyrusModelContributorResourceAdapter());
+ }
+ }
+ return null;
+ }
+
+ public Class<?>[] getAdapterList() {
+ return new Class[] { IContributorResourceAdapter.class };
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/CopyToClipboardAction.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/CopyToClipboardAction.java
new file mode 100644
index 00000000000..6e259be86e9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/CopyToClipboardAction.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.providers;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.actions.CopyResourceAction;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Copy to the clipboard the payrus model as 3 IResource
+ *
+ */
+public class CopyToClipboardAction extends CopyResourceAction {
+
+ protected Clipboard fClipboard;
+
+ public CopyToClipboardAction(IShellProvider shellProvider) {
+ super(shellProvider);
+ }
+
+ @Override
+ public void run() {
+ Display display = shellProvider.getShell().getDisplay();
+ fClipboard = new Clipboard(display);
+ IStructuredSelection structuredSelection = getStructuredSelection();
+ try {
+ copytoClipboardStructuredSelection(structuredSelection);
+ } finally {
+ fClipboard.dispose();
+ }
+ }
+
+
+ /**
+ * Copy in the clipboard the selection
+ *
+ * @param selection
+ */
+ public void copytoClipboardStructuredSelection(IStructuredSelection selection) {
+ Display display = Display.getCurrent();
+ Clipboard clipboard = new Clipboard(display);
+ Object[] array = selection.toArray();
+ IResource[] associatedResources = new IResource[array.length];
+ for (int i = 0; i < associatedResources.length; i++) {
+ Object object = array[i];
+ if (object instanceof IResource) {
+ associatedResources[i] = (IResource) object;
+ }
+ }
+ clipboard.setContents(new Object[] { associatedResources },
+ new Transfer[] { ResourceTransfer.getInstance() });
+ clipboard.dispose();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/OneFileDecorator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/OneFileDecorator.java
new file mode 100644
index 00000000000..2304bad368f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/OneFileDecorator.java
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan FAURE (Atos) tristan.faure@atos.net - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.providers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.IDecorationContext;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.decorators.DecorationBuilder;
+
+
+/**
+ * This decorator computes decoration of related files
+ * for each decoration an intersection is made
+ * and the {@link IPapyrusFile} will have the same decoration of the set
+ *
+ * @author tfaure
+ *
+ */
+@SuppressWarnings("restriction")
+public class OneFileDecorator extends LabelProvider implements ILightweightLabelDecorator {
+
+ public void decorate(Object element, IDecoration decoration) {
+ if (element instanceof IPapyrusFile) {
+ IPapyrusFile papy = (IPapyrusFile) element;
+ IResource[] associatedResources = papy.getAssociatedResources();
+ FilteredDecorationBuilder builder = new FilteredDecorationBuilder(decoration.getDecorationContext(), associatedResources.length);
+ for (IResource r : associatedResources) {
+ WorkbenchPlugin.getDefault().getDecoratorManager().getLightweightManager().getDecorations(r, builder);
+ }
+ builder.handleDecoration(decoration);
+ }
+ }
+
+ /**
+ * The builder which intercepts decoration
+ *
+ * @author tfaure
+ *
+ */
+ protected class FilteredDecorationBuilder extends DecorationBuilder {
+
+ /** overlay, prefix and suffixes can be several so the number of occurences is saved */
+ private Map<ImageDescriptor, Integer> overlay = new HashMap<ImageDescriptor, Integer>();
+
+
+ private Map<String, Integer> prefixString = new HashMap<String, Integer>();
+
+
+ private Map<String, Integer> suffixString = new HashMap<String, Integer>();
+
+
+ private Color bgColor = null;
+
+ private boolean flagBgColor = false;
+
+ private Font newFont = null;
+
+ private boolean flagNewFont = false;
+
+ private Color fgColor = null;
+
+ private boolean flagFgColor = false;
+
+ private final int nbResource;
+
+ public FilteredDecorationBuilder(IDecorationContext context, int nbResource) {
+ super(context);
+ this.nbResource = nbResource;
+ }
+
+ @Override
+ public void addOverlay(ImageDescriptor overlay) {
+ Integer result = this.overlay.get(overlay);
+ if (result == null) {
+ result = 0;
+ }
+ result++;
+ this.overlay.put(overlay, result);
+ }
+
+ @Override
+ public void addPrefix(String prefixString) {
+ Integer result = this.prefixString.get(prefixString);
+ if (result == null) {
+ result = 0;
+ }
+ result++;
+ this.prefixString.put(prefixString, result);
+ }
+
+ @Override
+ public void addSuffix(String suffixString) {
+ Integer result = this.suffixString.get(suffixString);
+ if (result == null) {
+ result = 0;
+ }
+ result++;
+ this.suffixString.put(suffixString, result);
+ }
+
+ @Override
+ public void setBackgroundColor(Color bgColor) {
+ if (this.bgColor == null && !flagBgColor) {
+ this.bgColor = bgColor;
+ flagBgColor = true;
+ } else if (this.bgColor != null && !this.bgColor.equals(bgColor)) {
+ this.bgColor = null;
+ }
+ }
+
+ @Override
+ public void setFont(Font newFont) {
+ if (this.newFont == null && !flagNewFont) {
+ this.newFont = newFont;
+ flagNewFont = true;
+ } else if (this.newFont != null && !this.newFont.equals(newFont)) {
+ this.newFont = null;
+ }
+ }
+
+ @Override
+ public void setForegroundColor(Color fgColor) {
+ if (this.fgColor == null && !flagFgColor) {
+ this.fgColor = fgColor;
+ flagFgColor = true;
+ } else if (this.fgColor != null && !this.fgColor.equals(fgColor)) {
+ this.fgColor = null;
+ }
+ }
+
+ public void handleDecoration(IDecoration decoration) {
+ if (fgColor != null) {
+ decoration.setForegroundColor(fgColor);
+ }
+ if (bgColor != null) {
+ decoration.setBackgroundColor(bgColor);
+ }
+ if (newFont != null) {
+ decoration.setFont(newFont);
+ }
+ for (ImageDescriptor desc : overlay.keySet()) {
+ if (overlay.get(desc) == nbResource) {
+ decoration.addOverlay(desc);
+ }
+ }
+ for (String s : prefixString.keySet()) {
+ if (prefixString.get(s) == nbResource) {
+ decoration.addPrefix(s);
+ }
+ }
+ for (String s : suffixString.keySet()) {
+ if (suffixString.get(s) == nbResource) {
+ decoration.addSuffix(s);
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusEditActionProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusEditActionProvider.java
new file mode 100644
index 00000000000..3c761b647f7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusEditActionProvider.java
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * 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:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.papyrus.infra.onefile.internal.ui.action.PapyrusModelPasteAction;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
+
+/**
+ * Action provider for paste Papyrus models
+ */
+public class PapyrusEditActionProvider extends CommonActionProvider {
+
+ private boolean fInViewPart = false;
+
+ private ICommonViewerWorkbenchSite workbenchSite;
+
+ private Action pasteAction;
+
+ public PapyrusEditActionProvider() {
+ }
+
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ super.fillActionBars(actionBars);
+ if (fInViewPart) {
+ actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteAction);
+ }
+ }
+
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+ if (pasteAction != null && pasteAction.isEnabled()) {
+ menu.insertAfter(PapyrusModelPasteAction.ID, pasteAction); // same as the internal org.eclipse.ui.internal.navigator.resources.actions.PasteAction.ID
+ menu.remove(PapyrusModelPasteAction.ID);
+ }
+ }
+
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ if (site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
+ workbenchSite = (ICommonViewerWorkbenchSite) site.getViewSite();
+ }
+ if (workbenchSite != null) {
+ if (workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) {
+ fInViewPart = true;
+ }
+ makeActions();
+ }
+ }
+
+ private void makeActions() {
+ final IWorkbenchPartSite provider = workbenchSite.getSite();
+
+ Shell shell = provider.getShell();
+ Clipboard clipboard = new Clipboard(shell.getDisplay());
+ pasteAction = new PapyrusModelPasteAction(shell, clipboard) {
+
+ // the helper is filtering Ipapyrus files
+
+ @Override
+ protected List getSelectedResources() {
+ ActionContext context = getContext();
+ List selectedResources = getSelectedResources(context);
+ return selectedResources;
+ }
+
+ protected List getSelectedResources(ActionContext context) {
+ ISelection selec = context.getSelection();
+ List<IResource> resources = new ArrayList<IResource>();
+
+ if (selec instanceof TreeSelection) {
+ TreeSelection tree = (TreeSelection) selec;
+ Object firstElement = tree.getFirstElement();
+ if (firstElement instanceof IResource) {
+ resources.add((IResource) firstElement);
+ }
+ }
+ return resources;
+ }
+ };
+
+ makeAction(pasteAction, IWorkbenchCommandConstants.EDIT_PASTE, ISharedImages.IMG_TOOL_PASTE, ISharedImages.IMG_TOOL_PASTE_DISABLED);
+ }
+
+ /**
+ * Create an action
+ *
+ * @param action
+ * @param id
+ * @param imgTool
+ * @param imgToolDisabled
+ */
+ protected void makeAction(Action action, String id, String imgTool, String imgToolDisabled) {
+ if (action != null) {
+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+ if (id != null) {
+ action.setId(id);
+ action.setActionDefinitionId(id);
+ }
+ if (imgTool != null) {
+ action.setImageDescriptor(images.getImageDescriptor(imgTool));
+ }
+ if (imgToolDisabled != null) {
+ action.setDisabledImageDescriptor(images.getImageDescriptor(imgToolDisabled));
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusModelActionProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusModelActionProvider.java
new file mode 100644
index 00000000000..626e22efcc1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/PapyrusModelActionProvider.java
@@ -0,0 +1,479 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration - 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Add copy Action
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor;
+import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.ltk.ui.refactoring.resource.RenameResourceWizard;
+import org.eclipse.papyrus.infra.onefile.internal.ui.Activator;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils;
+import org.eclipse.swt.SWT;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.DeleteResourceAction;
+import org.eclipse.ui.actions.MoveResourceAction;
+import org.eclipse.ui.actions.RefreshAction;
+import org.eclipse.ui.actions.RenameResourceAction;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Actions available through an {@link IPapyrusFile}
+ *
+ * @author tfaure
+ *
+ */
+@SuppressWarnings({ "restriction", "rawtypes" })
+public class PapyrusModelActionProvider extends CommonActionProvider {
+
+ private boolean fInViewPart = false;
+
+ private ICommonViewerWorkbenchSite workbenchSite;
+
+ private Action openAction;
+
+ private Action deleteAction;
+
+ private Action copyAction;
+
+ private Action renameAction;
+
+ private Action refreshAction;
+
+ private Action moveAction;
+
+ public PapyrusModelActionProvider() {
+
+ }
+
+ @Override
+ protected boolean filterAction(IAction action) {
+ return super.filterAction(action);
+ }
+
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ if (fInViewPart) {
+ actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction);
+ actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);
+ actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(), renameAction);
+ actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(), moveAction);
+ actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
+ actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), refreshAction);
+ }
+ super.fillActionBars(actionBars);
+ }
+
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+ appendToGroup(menu, openAction, ICommonMenuConstants.GROUP_OPEN);
+ appendToGroup(menu, deleteAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, moveAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, copyAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, renameAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, refreshAction, ICommonMenuConstants.GROUP_EDIT);
+ }
+
+ private void appendToGroup(IMenuManager menu, IAction action, String id) {
+ if (action != null && action.isEnabled()) {
+ menu.appendToGroup(id, action);
+ }
+ }
+
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ if (site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
+ workbenchSite = (ICommonViewerWorkbenchSite) site.getViewSite();
+ }
+ if (workbenchSite != null) {
+ if (workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) {
+ fInViewPart = true;
+ }
+ makeActions();
+ }
+ }
+
+ private void makeActions() {
+ final IWorkbenchPartSite provider = workbenchSite.getSite();
+ final ActionHelper helper = new ActionHelper();
+ openAction = new Action() {
+
+ @Override
+ public void run() {
+ if (getIFile() != null) {
+ try {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ page.openEditor(new FileEditorInput(getIFile()), "org.eclipse.papyrus.infra.core.papyrusEditor", true, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
+ } catch (WorkbenchException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+
+ public IFile getIFile() {
+ return helper.getIFile(getContext());
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return getIFile() != null;
+ }
+
+ @Override
+ public String getText() {
+ return IDEWorkbenchMessages.OpenFileAction_text;
+ }
+ };
+
+ deleteAction = new DeleteResourceAction(provider) {
+
+ @Override
+ public boolean isEnabled() {
+ return getSelectedResources() != null && getSelectedResources().size() > 0 && OneFileUtils.isDi((IResource) getSelectedResources().get(0));
+
+ }
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+ };
+
+ moveAction = new MoveResourceAction(provider) {
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+ };
+
+ copyAction = new CopyToClipboardAction(provider) {
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+
+ };
+
+ renameAction = new OneFileRenameAction(provider);
+
+ refreshAction = new RefreshAction(provider) {
+
+ @Override
+ public void run() {
+ super.run();
+ }
+
+ };
+
+ makeAction(openAction, ICommonActionConstants.OPEN, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
+ makeAction(deleteAction, IWorkbenchCommandConstants.EDIT_DELETE, ISharedImages.IMG_TOOL_DELETE, ISharedImages.IMG_TOOL_DELETE_DISABLED);
+ makeAction(moveAction, ActionFactory.MOVE.getId(), null, null);
+ makeAction(copyAction, IWorkbenchCommandConstants.EDIT_CUT, ISharedImages.IMG_TOOL_CUT, ISharedImages.IMG_TOOL_CUT_DISABLED);
+ makeAction(copyAction, IWorkbenchCommandConstants.EDIT_COPY, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
+ makeAction(refreshAction, ActionFactory.REFRESH.getCommandId(), null, null);
+ }
+
+ /**
+ * A Rename action applying to an IPapyrusFile
+ * The action will rename only the *.di file
+ * (Refactoring from infra.ui.resources will rename related files and fix URIs)
+ *
+ * The user won't be asked for a file extension (*.di will be kept)
+ *
+ * @author Camille Letavernier
+ */
+ public class OneFileRenameAction extends RenameResourceAction {
+
+ final ActionHelper helper = new ActionHelper();
+
+ private IWorkbenchPartSite partSiteProvider;
+
+ public OneFileRenameAction(IWorkbenchPartSite provider) {
+ super(provider);
+ this.partSiteProvider = provider;
+ }
+
+ private Shell getShell() {
+ return partSiteProvider.getShell();
+ }
+
+ @Override
+ public void run() {
+
+ ISelection selection = partSiteProvider.getSelectionProvider().getSelection();
+
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ if (structuredSelection.size() != 1) {
+ return;
+ }
+
+ Object selectedElement = structuredSelection.getFirstElement();
+ if (selectedElement instanceof IPapyrusFile) {
+ IPapyrusFile modelToRename = (IPapyrusFile) selectedElement;
+
+ RenamePapyrusModelWizard refactoringWizard = new RenamePapyrusModelWizard(modelToRename);
+ RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(refactoringWizard);
+ try {
+ op.run(getShell(), RefactoringUIMessages.RenameResourceHandler_title);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+ }
+
+ private static class RenamePapyrusModelWizard extends RenameResourceWizard {
+
+ private IPapyrusFile papyrusFile;
+
+ public RenamePapyrusModelWizard(IPapyrusFile papyrusFile) {
+ super(papyrusFile.getMainFile());
+ this.papyrusFile = papyrusFile;
+ }
+
+ @Override
+ protected void addUserInputPages() {
+ RenameResourceProcessor processor = getRefactoring().getAdapter(RenameResourceProcessor.class);
+ addPage(new RenamePapyrusModelPage(processor));
+ }
+
+ private class RenamePapyrusModelPage extends UserInputWizardPage {
+
+ private final RenameResourceProcessor fRefactoringProcessor;
+
+ private Text fNameField;
+
+ public RenamePapyrusModelPage(RenameResourceProcessor processor) {
+ super("RenamePapyrusModelRefactoringInputPage"); //$NON-NLS-1$
+ fRefactoringProcessor = processor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ composite.setFont(parent.getFont());
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(RefactoringUIMessages.RenameResourceWizard_name_field_label);
+ label.setLayoutData(new GridData());
+
+ fNameField = new Text(composite, SWT.BORDER);
+ fNameField.setText(papyrusFile.getMainFile().getFullPath().removeFileExtension().lastSegment());
+ fNameField.setFont(composite.getFont());
+ fNameField.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
+ fNameField.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ validatePage();
+ }
+ });
+
+ fNameField.selectAll();
+ setPageComplete(false);
+ setControl(composite);
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ fNameField.setFocus();
+ }
+ super.setVisible(visible);
+ }
+
+ protected final void validatePage() {
+ String text = fNameField.getText() + ".di";
+ RefactoringStatus status = fRefactoringProcessor.validateNewElementName(text);
+ setPageComplete(status);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish()
+ */
+ @Override
+ protected boolean performFinish() {
+ initializeRefactoring();
+ storeSettings();
+ return super.performFinish();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage()
+ */
+ @Override
+ public IWizardPage getNextPage() {
+ initializeRefactoring();
+ storeSettings();
+ return super.getNextPage();
+ }
+
+ private void storeSettings() {
+ }
+
+ private void initializeRefactoring() {
+ fRefactoringProcessor.setNewResourceName(fNameField.getText() + ".di");
+ }
+ }
+ }
+
+ protected void makeAction(Action action, String id, String imgTool, String imgToolDisabled) {
+ if (action != null) {
+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+ if (id != null) {
+ action.setId(id);
+ action.setActionDefinitionId(id);
+ }
+ if (imgTool != null) {
+ action.setImageDescriptor(images.getImageDescriptor(imgTool));
+ }
+ if (imgToolDisabled != null) {
+ action.setDisabledImageDescriptor(images.getImageDescriptor(imgToolDisabled));
+ }
+ }
+ }
+
+ public static class ActionHelper {
+
+ public IStructuredSelection getStructuredSelection(ActionContext context) {
+ return new StructuredSelection(getSelectedResources(context));
+ }
+
+ public List getOneSelectedResources(ActionContext context) {
+ List selectedResources = getSelectedResources(context);
+ if (selectedResources.size() > 0) {
+ for (Iterator<?> i = selectedResources.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IFile) {
+ IFile file = (IFile) o;
+ if (!OneFileUtils.isDi(file)) {
+ i.remove();
+ }
+ }
+ }
+ return selectedResources;
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ public IStructuredSelection getOneStructuredSelection(ActionContext context) {
+ List selectedResources = getOneSelectedResources(context);
+ if (selectedResources.size() > 0) {
+ return new StructuredSelection(selectedResources);
+ }
+ return null;
+ }
+
+ protected List getSelectedResources(ActionContext context) {
+ ISelection selec = context.getSelection();
+ List<IResource> resources = new ArrayList<IResource>();
+ if (selec instanceof IStructuredSelection) {
+ IStructuredSelection struc = (IStructuredSelection) selec;
+ for (Iterator<Object> i = struc.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IPapyrusFile) {
+ IPapyrusFile papy = (IPapyrusFile) o;
+ resources.addAll(Arrays.asList(papy.getAssociatedResources()));
+ }
+ }
+ }
+ return resources;
+ }
+
+ public IFile getIFile(ActionContext context) {
+ ISelection selec = context.getSelection();
+ if (selec instanceof IStructuredSelection) {
+ IStructuredSelection struc = (IStructuredSelection) selec;
+ Object firstElement = struc.getFirstElement();
+ if (firstElement instanceof IFile) {
+ IFile file = (IFile) firstElement;
+ return file;
+ } else if (firstElement instanceof IPapyrusFile) {
+ return ((IPapyrusFile) firstElement).getMainFile();
+ }
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/SubresourceFileActionProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/SubresourceFileActionProvider.java
new file mode 100644
index 00000000000..8d365c04aff
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/providers/SubresourceFileActionProvider.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration - 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:
+ * Tristan Faure (Atos Origin) tristan.faure@atos.net - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.internal.ui.providers;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.internal.navigator.resources.actions.EditActionProvider;
+
+
+/**
+ * An edit action provider to provide Copy/Paste/Delete on sub resources
+ *
+ * @author Tristan Faure
+ *
+ */
+@SuppressWarnings("restriction")
+public class SubresourceFileActionProvider extends EditActionProvider {
+
+ @Override
+ public void setContext(ActionContext context) {
+ // TODO Auto-generated method stub
+ List<Object> resources = new LinkedList<Object>();
+ if (context.getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection contextSelec = (IStructuredSelection) context.getSelection();
+ for (Iterator<?> i = contextSelec.iterator(); i.hasNext();) {
+ Object o = i.next();
+ IResource res = adapt(o, IResource.class);
+ if (res != null) {
+ resources.add(res);
+ }
+ }
+ }
+ if (!resources.isEmpty()) {
+ ISelection selec = new StructuredSelection(resources);
+ super.setContext(new ActionContext(selec));
+ } else {
+ super.setContext(context);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T adapt(Object o, Class<T> aClass) {
+ T result = null;
+ if (aClass.isInstance(o)) {
+ result = (T) o;
+ }
+ if (o instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) o;
+ result = (T) adaptable.getAdapter(aClass);
+ }
+ if (result == null) {
+ result = (T) Platform.getAdapterManager().getAdapter(o, aClass);
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/testers/PapyrusClipboardTester.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/testers/PapyrusClipboardTester.java
new file mode 100644
index 00000000000..ac0c3a33a55
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/internal/ui/testers/PapyrusClipboardTester.java
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * 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:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.internal.ui.testers;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Papyrus tester on clipboard contents
+ * containsPapyrusModel : test if there is a papyrus model
+ */
+public class PapyrusClipboardTester extends PropertyTester {
+
+ public static final String CLIPBOARD_CONTAINS_PAPYRUS_MODEL = "containsPapyrusModel"; //$NON-NLS-1$
+
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (receiver instanceof org.eclipse.swt.widgets.Shell) {
+ Clipboard clipboard = new Clipboard(Display.getDefault());
+ if (CLIPBOARD_CONTAINS_PAPYRUS_MODEL.equals(property)) {
+ boolean answer = containsPapyrusModel(clipboard);
+ return new Boolean(answer).equals(expectedValue);
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Test if the clipboard contains some Papyrus model (that is with a di extension)
+ *
+ * @param clipboard
+ * @return
+ */
+ protected boolean containsPapyrusModel(Clipboard clipboard) {
+ if (clipboard != null) {
+ String[] filePaths = (String[]) clipboard.getContents(FileTransfer.getInstance());
+ if (filePaths != null) {
+ if (filePaths.length > 0) {
+ for (int i = 0; i < filePaths.length; i++) {
+ if (filePaths[i].endsWith("." + DiModel.MODEL_FILE_EXTENSION)) { //$NON-NLS-1$
+ return true;
+ }
+ }
+ }
+ } else {
+ IResource[] resources = (IResource[]) clipboard.getContents(ResourceTransfer.getInstance());
+ if (resources != null) {
+ if (resources.length > 0) {
+ for (int i = 0; i < resources.length; i++) {
+ if (DiModel.MODEL_FILE_EXTENSION.equals(resources[i].getFileExtension())) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusContentProvider.java
new file mode 100644
index 00000000000..4f06cac9c5b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusContentProvider.java
@@ -0,0 +1,307 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration - 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.ui.providers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.onefile.internal.ui.Activator;
+import org.eclipse.papyrus.infra.onefile.internal.ui.filters.OnlyDiFilter;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.papyrus.infra.onefile.model.PapyrusModelHelper;
+import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * Content provider able to retrieve Papyrus children from an {@link IContainer}
+ *
+ * @author Tristan FAURE
+ *
+ */
+public class PapyrusContentProvider extends WorkbenchContentProvider {
+
+
+ private CommonViewer common;
+
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ if (viewer instanceof CommonViewer) {
+ common = (CommonViewer) viewer;
+ }
+ }
+
+ /**
+ * Determine if the current navigator is filtered or not
+ *
+ * @return true if the viewer is filtered
+ */
+ public boolean isFiltered() {
+ return common != null && common.getNavigatorContentService() != null && common.getNavigatorContentService().getFilterService() != null && common.getNavigatorContentService().getFilterService().isActive(OnlyDiFilter.FILTER_ID);
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof IWorkspaceRoot) {
+ return null;
+ }
+ List<Object> result = new LinkedList<Object>();
+ try {
+ if (isFiltered()) {
+ if (inputElement instanceof IPapyrusFile) {
+ IPapyrusFile file = (IPapyrusFile) inputElement;
+ for (IResource r : file.getAssociatedResources()) {
+ result.add(PapyrusModelHelper.getPapyrusModelFactory().createISubResourceFile(file, (IFile) r));
+ }
+ } else {
+ IResource[] members = null;
+ if (inputElement instanceof IContainer) {
+ IContainer container = (IContainer) inputElement;
+ if (container.isAccessible()) {
+ members = container.members();
+ }
+ }
+ if (members != null) {
+ for (IResource r : members) {
+ if (r instanceof IFile) {
+ if (OneFileUtils.isDi(r)) {
+ IPapyrusFile createIPapyrusFile = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile((IFile) r);
+ result.add(createIPapyrusFile);
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ return result.isEmpty() ? null : result.toArray();
+ }
+
+ @Override
+ public Object[] getChildren(Object inputElement) {
+ return getElements(inputElement);
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ if (element instanceof IPapyrusFile) {
+ IPapyrusFile papyFile = (IPapyrusFile) element;
+ return papyFile.getParent();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return OneFileUtils.hasChildren(element);
+ }
+
+ @Override
+ protected void processDelta(IResourceDelta delta) {
+ super.processDelta(delta);
+ if (!isFiltered()) {
+ return;
+ }
+ Control ctrl = common.getControl();
+ if (ctrl == null || ctrl.isDisposed()) {
+ return;
+ }
+
+
+ final Collection<Runnable> runnables = new ArrayList<Runnable>();
+ processPapyrusDelta(delta, runnables);
+
+ if (runnables.isEmpty()) {
+ return;
+ }
+
+ // Are we in the UIThread? If so spin it until we are done
+ ctrl.getDisplay().asyncExec(new Runnable() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ // Abort if this happens after disposes
+ Control ctrl = common.getControl();
+ if (ctrl == null || ctrl.isDisposed()) {
+ return;
+ }
+ runUpdates(runnables);
+ }
+ });
+
+ }
+
+ private void runUpdates(Collection<?> runnables) {
+ Iterator<?> runnableIterator = runnables.iterator();
+ while (runnableIterator.hasNext()) {
+ ((Runnable) runnableIterator.next()).run();
+ }
+
+ }
+
+ protected void processPapyrusDelta(IResourceDelta delta, Collection<Runnable> runnables) {
+ IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED);
+
+ // Handle changed children .
+ for (int i = 0; i < affectedChildren.length; i++) {
+ processPapyrusDelta(affectedChildren[i], runnables);
+ }
+
+ IResourceDelta[] addedChildren = delta.getAffectedChildren(IResourceDelta.ADDED);
+
+ IResourceDelta[] removedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED);
+
+ final Object[] addedObjects;
+
+ final Object[] removedObjects;
+
+ // Process additions before removals as to not cause selection
+ // preservation prior to new objects being added
+ // Handle added children. Issue one update for all insertions.
+ if (addedChildren.length > 0) {
+ addedObjects = new Object[addedChildren.length];
+ for (int i = 0; i < addedChildren.length; i++) {
+ addedObjects[i] = addedChildren[i].getResource();
+ }
+ } else {
+ addedObjects = new Object[0];
+ }
+
+ removedObjects = new Object[removedChildren.length];
+ int i = 0;
+ for (IResourceDelta removeDelta : removedChildren) {
+ removedObjects[i++] = removeDelta.getResource();
+ }
+
+ // Handle removed children. Issue one update for all removals.
+ // heuristic test for items moving within same folder (i.e. renames)
+ Runnable addAndRemove = new Runnable() {
+
+ public void run() {
+ if (common instanceof AbstractTreeViewer && common.getControl() != null && !common.getControl().isDisposed()) {
+ // Disable redraw until the operation is finished so we don't
+ // get a flash of both the new and old item (in the case of
+ // rename)
+ // Only do this if we're both adding and removing files (the
+ // rename case)
+
+ // need to handle resource addition
+ if (addedObjects.length > 0) {
+ Set<Object> toRefresh = new HashSet<Object>();
+ Set<IPapyrusFile> toAdd = new HashSet<IPapyrusFile>(addedObjects.length);
+ for (Object r : addedObjects) {
+ if (r instanceof IResource) {
+ IResource current = (IResource) r;
+ if (OneFileUtils.diExists(current.getName(), current.getParent())) {
+ IPapyrusFile oneFile = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(OneFileUtils.getDi(current.getName(), current.getParent()));
+ toRefresh.add(oneFile);
+ toRefresh.add(oneFile.getParent());
+ }
+
+ if (OneFileUtils.isDi(current)) {
+ toAdd.add(PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile((IFile) current));
+ }
+ }
+ }
+
+ for (IPapyrusFile o : toAdd) {
+ common.add(o.getParent(), o);
+ }
+
+ for (Object o : toRefresh) {
+ common.refresh(o);
+ }
+ }
+
+ if (removedObjects.length > 0) {
+
+ Set<Object> toRefresh = new HashSet<Object>();
+ Set<Object> toRemove = new HashSet<Object>();
+
+ for (Object r : removedObjects) {
+ if (r instanceof IResource) {
+ IResource current = (IResource) r;
+ if (OneFileUtils.isDi(current)) {
+ toRemove.add(PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile((IFile) current));
+ toRefresh.add(current.getParent());
+ } else if (OneFileUtils.diExists(current.getName(), current.getParent())) {
+ IPapyrusFile oneFile = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(OneFileUtils.getDi(current.getName(), current.getParent()));
+ toRefresh.add(oneFile);
+ toRemove.add(PapyrusModelHelper.getPapyrusModelFactory().createISubResourceFile(oneFile, (IFile) current));
+ }
+ }
+ }
+
+ common.remove(toRemove.toArray());
+
+ for (Object o : toRefresh) {
+ common.refresh(o);
+ }
+ }
+ }
+ }
+ };
+ runnables.add(addAndRemove);
+ }
+
+ // @Override
+ // protected ITreeContentProvider getDelegateContentProvider() {
+ // if(provider == null) {
+ // provider = new WorkbenchContentProvider();
+ // }
+ // return provider;
+ // }
+ //
+ // @Override
+ // protected String getModelProviderId() {
+ // return OneFileModelProvider.MODEL_PROVIDER_ID;
+ // }
+ //
+ // @Override
+ // protected Object getModelRoot() {
+ // return null;
+ // }
+
+ // @Override
+ // protected ResourceTraversal[] getTraversals(ISynchronizationContext context, Object object) {
+ // return null;
+ // }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusLabelProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusLabelProvider.java
new file mode 100644
index 00000000000..acb1cf0ce5a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusLabelProvider.java
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 Atos Origin Integration, 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.ui.providers;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.papyrus.infra.onefile.model.ISubResourceFile;
+import org.eclipse.papyrus.infra.ui.util.PapyrusImageUtils;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Label Provider for Papyrus Model Elements
+ *
+ * @author tristan.faure@atosorigin.com
+ *
+ */
+public class PapyrusLabelProvider implements ILabelProvider {
+
+ private ImageRegistry images = new ImageRegistry(JFaceResources.getResources());
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void dispose() {
+ images.dispose();
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return true;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+ public Image getImage(Object element) {
+ if (element instanceof IPapyrusFile) {
+ return PapyrusImageUtils.getDefaultIcon();
+ }
+ if (element instanceof ISubResourceFile) {
+ IFile file = ((ISubResourceFile) element).getFile();
+ String ext = file.getFileExtension();
+ Image image = images.get(ext);
+ if (image == null) {
+ ImageDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getImageDescriptor(file.getName());
+ images.put(ext, desc);
+ }
+ return images.get(ext);
+ }
+ return null;
+ }
+
+ public String getText(Object element) {
+ if (element instanceof IPapyrusFile) {
+ IPapyrusFile papyFile = (IPapyrusFile) element;
+ return papyFile.getText();
+ }
+ if (element instanceof ISubResourceFile) {
+ return ((ISubResourceFile) element).getText();
+ }
+ if (element instanceof IResource) {
+ return ((IResource) element).getName();
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusViewerSorter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusViewerSorter.java
new file mode 100644
index 00000000000..05fff62f22a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/providers/PapyrusViewerSorter.java
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.ui.providers;
+
+import java.text.Collator;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.ui.views.navigator.ResourceComparator;
+
+/**
+ * Sort Papyrus Files according to their Main File
+ *
+ * @author tristan.faure@atosorigin.com
+ */
+public class PapyrusViewerSorter extends ViewerSorter {
+
+ /**
+ * {@link ResourceComparator} for comparison delegation
+ */
+ ResourceComparator comp = new ResourceComparator(ResourceComparator.TYPE);
+
+ public PapyrusViewerSorter() {
+ super();
+ }
+
+ public PapyrusViewerSorter(Collator collator) {
+ super(collator);
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (e1 instanceof IPapyrusFile) {
+ IPapyrusFile papyrusFile = (IPapyrusFile) e1;
+ e1 = papyrusFile.getMainFile();
+ }
+ if (e2 instanceof IPapyrusFile) {
+ IPapyrusFile papyrusFile = (IPapyrusFile) e2;
+ e2 = papyrusFile.getMainFile();
+ }
+ return comp.compare(viewer, e1, e2);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/utils/OneFileUIUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/utils/OneFileUIUtils.java
new file mode 100644
index 00000000000..b231fb1ae58
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.onefile.ui/src/org/eclipse/papyrus/infra/onefile/ui/utils/OneFileUIUtils.java
@@ -0,0 +1,210 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 Atos Origin Integration, 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.ui.utils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.infra.onefile.internal.ui.Activator;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Utility methods for the UI
+ *
+ * @author tristan.faure@atosorigin.com
+ *
+ */
+public class OneFileUIUtils {
+
+ /**
+ * Check if the object is in an already opened editor
+ *
+ * @param inputElement
+ * @return
+ */
+ public static IEditorPart isOpenInEditor(Object inputElement) {
+ IEditorPart editor = findEditor(inputElement, false);
+ if (editor != null) {
+ return editor;
+ }
+ IEditorInput input = getEditorInput(inputElement);
+ if (input != null) {
+
+ IWorkbenchPage p = getActivePage();
+ if (p != null) {
+ return p.findEditor(input);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find an editor opening the input element
+ *
+ * @param inputElement
+ * @param activate
+ * , if activate is true, once the editor is found it is
+ * activated
+ * @return null if no editor is found
+ */
+ private static IEditorPart findEditor(Object inputElement, boolean activate) {
+ if (inputElement instanceof IPapyrusFile) {
+ IPapyrusFile cu = (IPapyrusFile) inputElement;
+ if (cu != null) {
+ IWorkbenchPage page = getActivePage();
+ for (IEditorReference ref : page.getEditorReferences()) {
+ IEditorPart editor = ref.getEditor(false);
+ if (editor != null) {
+ IEditorInput editorInput;
+ editorInput = editor.getEditorInput();
+ if (cu.getMainFile().equals(editorInput.getAdapter(IFile.class))) {
+ if (activate && page.getActivePart() != editor) {
+ page.activate(editor);
+ }
+ return editor;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Open the editor corresponding to the inpur element
+ *
+ * @param inputElement
+ * @param activate
+ * @return
+ * @throws PartInitException
+ */
+ public static IEditorPart openInEditor(Object inputElement, boolean activate) throws PartInitException {
+
+ if (inputElement instanceof IFile) {
+ return openInEditor((IFile) inputElement, activate);
+ }
+ IEditorPart editor = findEditor(inputElement, activate);
+ if (editor != null) {
+ return editor;
+ }
+ IEditorInput input = getEditorInput(inputElement);
+ if (input == null) {
+ throw new PartInitException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "not found"));
+ }
+ return openInEditor(input, getEditorID(input), activate);
+ }
+
+ /**
+ * Get the editor input for the given element
+ *
+ * @param inputElement
+ * @return
+ */
+ private static IEditorInput getEditorInput(Object inputElement) {
+ if (inputElement instanceof IFile) {
+ IFile file = (IFile) inputElement;
+ return new FileEditorInput(file);
+ }
+ return null;
+ }
+
+ /**
+ * Get the editor id for an editor input
+ *
+ * @param input
+ * @return
+ * @throws PartInitException
+ */
+ public static String getEditorID(IEditorInput input) throws PartInitException {
+
+ Assert.isNotNull(input);
+
+ IEditorDescriptor editorDescriptor;
+
+ if (input instanceof IFileEditorInput) {
+ editorDescriptor = IDE.getEditorDescriptor(((IFileEditorInput) input).getFile());
+ } else {
+ editorDescriptor = IDE.getEditorDescriptor(input.getName());
+ }
+ return editorDescriptor.getId();
+
+ }
+
+ /**
+ * @param file
+ * @param activate
+ * @return
+ * @throws PartInitException
+ */
+ private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
+
+ if (file == null) {
+ throw new PartInitException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "not found"));
+ }
+
+ IWorkbenchPage p = getActivePage();
+
+ if (p == null) {
+ throw new PartInitException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "not found"));
+ }
+
+ IEditorPart editorPart = IDE.openEditor(p, file, activate);
+
+ return editorPart;
+
+ }
+
+ /**
+ * Get the active Page
+ *
+ * @return
+ */
+ public static IWorkbenchPage getActivePage() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench == null) {
+ return null;
+ }
+ IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbenchWindow == null) {
+ return null;
+ }
+ return activeWorkbenchWindow.getActivePage();
+ }
+
+ private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException {
+ Assert.isNotNull(input);
+ Assert.isNotNull(editorID);
+ IWorkbenchPage p = getActivePage();
+ if (p == null) {
+ throw new PartInitException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "not found"));
+ }
+ IEditorPart editorPart = p.openEditor(input, editorID, activate);
+ return editorPart;
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.classpath b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.classpath
new file mode 100644
index 00000000000..64c5e31b7a2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.project b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.project
new file mode 100644
index 00000000000..1233f09c6e8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.infra.ui.resources</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..c585cc455ae
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,291 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=260
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=260
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.ui.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..954281dbc31
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,68 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Papyrus
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Papyrus
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..e4d2acb77b8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
+ org.eclipse.ltk.core.refactoring;bundle-version="3.5.200",
+ org.eclipse.papyrus.infra.services.controlmode.history;bundle-version="1.2.0",
+ org.eclipse.emf.transaction;bundle-version="1.4.0",
+ org.eclipse.ui.ide;bundle-version="3.8.0",
+ org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.emf.readonly;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.2.0",
+ com.google.guava;bundle-version="11.0.0",
+ org.eclipse.papyrus.infra.ui;bundle-version="1.2.0"
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.2.0.qualifier
+Bundle-Localization: plugin
+Bundle-Name: %pluginName
+Bundle-Activator: org.eclipse.papyrus.infra.ui.resources.Activator
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.papyrus.infra.ui.resources;singleton:=true
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/about.html b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/about.html
new file mode 100644
index 00000000000..dd3c089a94c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 14, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/build.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/build.properties
new file mode 100644
index 00000000000..ad003b17745
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/build.properties
@@ -0,0 +1,11 @@
+#
+#Mon Sep 12 09:30:21 CEST 2011
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ about.html
+output..=bin/
+src.includes = about.html
+source..=src/
+bin..=bin/
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.properties
new file mode 100644
index 00000000000..86c901d6502
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.properties
@@ -0,0 +1,15 @@
+#################################################################################
+# Copyright (c) 2011 Atos Origin.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Arthur Daussy arthur.daussy@atosorigin.com - Initial API and implementation
+##################################################################################
+pluginName=Papyrus plugin for refactoring resources
+providerName=Eclipse Modeling Project
+renameParticipant.name = Papyrus Model Renaming
+deleteParticipant.name = Papyrus Model deleting
+moveParticipant.name = Papyrus Model Moving \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.xml
new file mode 100644
index 00000000000..a35209c09a5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/plugin.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ltk.core.refactoring.renameParticipants">
+ <renameParticipant
+ class="org.eclipse.papyrus.infra.ui.resources.refactoring.RenameModelParticipant"
+ id="org.eclipse.papyrus.ui.resources.renameParticipant"
+ name="%renameParticipant.name">
+ <enablement>
+ <with
+ variable="element">
+ <instanceof
+ value="org.eclipse.core.resources.IFile">
+ </instanceof>
+ </with>
+ </enablement>
+ </renameParticipant>
+ </extension>
+
+</plugin>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/pom.xml
new file mode 100644
index 00000000000..a42585307dd
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.infra.ui.resources</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/Activator.java
new file mode 100644
index 00000000000..d6aee281d63
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/Activator.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2010 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Atos Origin - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+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.ui.resources"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /** The log service */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(plugin);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/DirtyEditorChange.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/DirtyEditorChange.java
new file mode 100644
index 00000000000..6d47696bbfa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/DirtyEditorChange.java
@@ -0,0 +1,146 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.util.EditorUtils;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * A change that checks if an editor is actually editing the model and if it must be save.
+ *
+ * @author tszadel
+ *
+ */
+public class DirtyEditorChange extends Change {
+
+ private final IFile oldFile;
+
+ private final IFile newFile;
+
+ /**
+ * Constructor.
+ *
+ * @param resourceSet
+ * The resource set being changed.
+ * @param oldFile
+ * The old file.
+ * @param newFile
+ * The new file.
+ */
+ public DirtyEditorChange(IFile oldFile, IFile newFile) {
+ this.oldFile = oldFile;
+ this.newFile = newFile;
+ }
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement()
+ *
+ * @return
+ */
+
+ @Override
+ public Object getModifiedElement() {
+ return oldFile;
+ }
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.Change#getName()
+ *
+ * @return
+ */
+
+ @Override
+ public String getName() {
+ return Messages.DirtyEditorChange_0;
+ }
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param pm
+ */
+
+ @Override
+ public void initializeValidationData(IProgressMonitor pm) {
+ // Nothing
+ }
+
+
+ private boolean hasDirtyEditors() {
+ IMultiDiagramEditor[] list = EditorUtils.getRelatedEditors(oldFile);
+ if (list != null && list.length > 0) {
+ for (IMultiDiagramEditor editor : list) {
+ if (editor.isDirty()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param pm
+ * The progress monitor.
+ * @return The status.
+ * @throws CoreException
+ * Error.
+ * @throws OperationCanceledException
+ * Operation canceled.
+ */
+
+ @Override
+ public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ final RefactoringStatus status = new RefactoringStatus();
+ // We need to get the current workbench... so we have to use the UI-Thread!
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ if (hasDirtyEditors()) {
+ if (!MessageDialog.openConfirm(Display.getDefault().getActiveShell(), Messages.DirtyEditorChange_1, Messages.DirtyEditorChange_2)) {
+ status.addFatalError(Messages.DirtyEditorChange_3);
+ }
+ }
+ }
+ });
+
+ return status;
+ }
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param pm
+ * The progress monitor.
+ * @return The change used to undo.
+ * @throws CoreException
+ * Error.
+ */
+
+ @Override
+ public Change perform(IProgressMonitor pm) throws CoreException {
+ // Nothing to do
+ return new DirtyEditorChange(newFile, oldFile);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/Messages.java
new file mode 100644
index 00000000000..05dfba882d1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/Messages.java
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Arthur Daussy - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.ui.resources.refactoring.messages"; //$NON-NLS-1$
+
+ public static String DirtyEditorChange_0;
+
+ public static String DirtyEditorChange_1;
+
+ public static String DirtyEditorChange_2;
+
+ public static String DirtyEditorChange_3;
+
+ public static String MoveModelParticipant_Name;
+
+ public static String RenameModelChange_0;
+
+ public static String RenameModelChange_5;
+
+ public static String RenameModelChange_6;
+
+ public static String RenameModelChange_7;
+
+ public static String RenameModelChange_8;
+
+ public static String RenameModelChange_Change;
+
+ public static String RenameModelChange_DaveDirtyEditor;
+
+ public static String RenameModelChange_ErrorLoading;
+
+ public static String RenameModelChange_LoadingEMF;
+
+ public static String RenameModelChange_ModifyURI;
+
+ public static String RenameModelChange_Name;
+
+ public static String RenameModelChange_RemoveOldFile;
+
+ public static String RenameModelChange_savingResource;
+
+ public static String RenameModelChange_Unloading;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ModelParticipantHelpers.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ModelParticipantHelpers.java
new file mode 100644
index 00000000000..865a40d590f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ModelParticipantHelpers.java
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 Atos Origin, 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:
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 436377
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.papyrus.infra.ui.resources.refactoring.ui.RenameParticipantsDialog;
+import org.eclipse.swt.widgets.Display;
+
+public class ModelParticipantHelpers {
+
+ /**
+ * get the files related the initialFile which need to be modified/deleted
+ * if initialFile is modified/deleted
+ *
+ * @param initialFile
+ * @return a list of related files. Does not include initialFile.
+ *
+ * @throws OperationCanceledException
+ * if user interaction is required to determine the resources to fix and the user elects to cancel that analysis
+ */
+ public static Set<IResource> getResourceToFix(final IFile initialFile) throws OperationCanceledException {
+
+ RenameDialogRunnable runnable = new RenameDialogRunnable(initialFile);
+ Display.getDefault().syncExec(runnable);
+
+ if (runnable.wasCancelled()) {
+ throw new OperationCanceledException();
+ }
+
+ return new HashSet<IResource>(runnable.getFiles());
+ }
+
+ /**
+ * get the files related the initialFile which need to be modified/deleted
+ * if initialFile is modified/deleted
+ *
+ * @param initialFile
+ * @return a list of related files. Does not include initialFile.
+ */
+ public static Set<IResource> getRelatedFiles(final IFile initialFile) {
+
+
+ IContainer parent = initialFile.getParent();
+ IPath initialPath = initialFile.getFullPath();
+
+ IPath diPath = null;
+
+ if (DiModel.DI_FILE_EXTENSION.equalsIgnoreCase(initialPath.getFileExtension())) {
+ diPath = initialPath;
+ } else {
+ return Collections.<IResource> singleton(initialFile);
+ }
+
+ Set<IResource> relatedFiles = new HashSet<IResource>();
+ if (diPath != null) {
+ IFile diFile = parent.getFile(diPath.makeRelativeTo(parent.getFullPath()));
+ if (diFile.exists()) {
+ try {
+ for (IResource r : diFile.getParent().members()) {
+ if (r.getFullPath().removeFileExtension().lastSegment().equals(diFile.getFullPath().removeFileExtension().lastSegment())) {
+ relatedFiles.add(r);
+ }
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+
+ // If the initialFile is contained in the list, we remove it
+ if (relatedFiles.contains(initialFile)) {
+ relatedFiles.remove(initialFile);
+ }
+
+
+
+ return relatedFiles;
+ }
+
+ public static class RenameDialogRunnable implements Runnable {
+
+ private IFile initialFile;
+
+ private RenameParticipantsDialog renameParticipantsDialog;
+
+ public RenameDialogRunnable(IFile file) {
+ initialFile = file;
+ }
+
+ public void run() {
+ renameParticipantsDialog = new RenameParticipantsDialog(Display.getDefault().getActiveShell(), initialFile);
+ renameParticipantsDialog.open();
+ }
+
+ public Collection<? extends IResource> getFiles() {
+ return renameParticipantsDialog.getFiles();
+ }
+
+ public boolean wasCancelled() {
+ return renameParticipantsDialog.getReturnCode() != Window.OK;
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelChange.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelChange.java
new file mode 100644
index 00000000000..423ca667e16
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelChange.java
@@ -0,0 +1,532 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Atos Origin - 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:
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Save only modified resources and delete only old version of renamed resources
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring;
+
+import static org.eclipse.papyrus.infra.ui.resources.Activator.log;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.core.modelsetquery.IModelSetQueryAdapter;
+import org.eclipse.papyrus.infra.core.modelsetquery.ModelSetQuery;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.ModelsReader;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModelUtils;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.readonly.ReadOnlyManager;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.emf.utils.ResourceUtils;
+import org.eclipse.papyrus.infra.services.controlmode.mm.history.ControledResource;
+import org.eclipse.papyrus.infra.services.controlmode.mm.history.historyPackage;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.resources.Activator;
+import org.eclipse.papyrus.infra.ui.util.EditorUtils;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Rename the model.<BR>
+ * <b>Note</b>: That change should be called inside a rename operation as it assumes that a {@link RenameResourceChange} occured.
+ *
+ * @author tszadel
+ *
+ */
+public class RenameModelChange extends Change {
+
+ private final Map<URI, URI> uriMap = new HashMap<URI, URI>();
+
+ private final IFile oldFile;
+
+ private final IFile newFile;
+
+ private final Set<IResource> relatedFiles;
+
+ private final Collection<? extends IResource> impacted;
+
+ private TransactionalEditingDomain domain;
+
+ private ModelSet resourceSet;
+
+ private List<IMultiDiagramEditor> openedEditors;
+
+ private boolean isUndoOperation;
+
+ /**
+ * Constructor.
+ *
+ * @param resourceSet
+ * The resource set being changed.
+ * @param oldFile
+ * The old file.
+ * @param newFile
+ * The new file.
+ * @param impacted
+ */
+ public RenameModelChange(IFile oldFile, IFile newFile, Collection<? extends IResource> impacted) {
+ this.oldFile = oldFile;
+ this.newFile = newFile;
+ this.impacted = impacted;
+
+ IPath newPathWithoutExt = newFile.getFullPath().removeFileExtension();
+
+ // Create the map of URI that are being modified in the resource set
+ relatedFiles = ModelParticipantHelpers.getRelatedFiles(oldFile);
+ relatedFiles.add(oldFile);
+
+ for (IResource iResource : relatedFiles) {
+ IPath path = iResource.getFullPath();
+ URI oldURI = getPlatformURI(path);
+ URI newURI = getPlatformURI(newPathWithoutExt.addFileExtension(path.getFileExtension()));
+ uriMap.put(oldURI, newURI);
+ }
+ }
+
+ /**
+ * Overrides getModifiedElement.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement()
+ */
+ @Override
+ public Object getModifiedElement() {
+ return oldFile;
+ }
+
+ /**
+ * Overrides getName.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.Change#getName()
+ */
+ @Override
+ public String getName() {
+ return NLS.bind(Messages.RenameModelChange_Name, oldFile.getName());
+ }
+
+ /**
+ * Overrides initializeValidationData.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void initializeValidationData(IProgressMonitor pm) {
+ // Nothing
+ }
+
+ /**
+ * Overrides isValid.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ // That change assumes that the model resource has already been renamed
+ // So, the first thing to do is to get the new file, to restore it in order
+ // to change all the resources.
+ pm.subTask(Messages.RenameModelChange_LoadingEMF);
+
+ pm.subTask(Messages.RenameModelChange_DaveDirtyEditor);
+ // We need to get the current workbench... so we have to use the UI-Thread!
+ openedEditors = new ArrayList<IMultiDiagramEditor>();
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ IMultiDiagramEditor[] multiEditors = EditorUtils.getRelatedEditors(oldFile);
+ if (multiEditors != null && multiEditors.length > 0) {
+ for (IMultiDiagramEditor editor : multiEditors) {
+ if (editor.isDirty()) {
+ editor.doSave(new NullProgressMonitor());
+ }
+ openedEditors.add(editor);
+ }
+ }
+ }
+ });
+ pm.worked(10);
+
+ /*
+ * Load ModelSet
+ */
+ resourceSet = new ModelSet();
+ try {
+ ModelsReader reader = new ModelsReader();
+ reader.readModel(resourceSet);
+ resourceSet.loadModels(oldFile);
+ for (IResource r : impacted) {
+ if (r instanceof IFile) {
+ IFile file = (IFile) r;
+ try {
+ resourceSet.getResource(URI.createPlatformResourceURI(file.getFullPath().toString(), true), true);
+ } catch (Exception e) {
+ // to avoid load errors
+ }
+ }
+ }
+ } catch (Exception e) {
+ Activator.log.error(e);
+ }
+
+ // Force EMF resolve and load all the resources
+ try {
+ EcoreUtil.resolveAll(resourceSet);
+ } catch (Exception ex) {
+ // the resolve all does not have to break the operation
+ }
+
+ pm.worked(4);
+ domain = resourceSet.getTransactionalEditingDomain();
+
+ // TODO improve when impact analysis will be effective
+ return manageResourceSet(pm, resourceSet);
+ }
+
+ /**
+ * Get a platform resource URI of the given path
+ *
+ * @param path
+ * the path
+ * @return the uri
+ */
+ private URI getPlatformURI(IPath path) {
+ return URI.createPlatformResourceURI(path.toString(), true);
+ }
+
+ /**
+ * Overrides perform.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public Change perform(IProgressMonitor pm) throws CoreException {
+
+ String lMsg = NLS.bind(Messages.RenameModelChange_Change, oldFile.getName(), newFile.getName());
+ isUndoOperation = oldFile.exists() && !newFile.exists();
+
+ if (!isUndoOperation) {
+ // The file has already been renamed. Undo the rename change, then do the full refactoring in the resource set
+ newFile.move(oldFile.getFullPath(), true, new SubProgressMonitor(pm, 1));
+ }
+
+ Set<IResource> revertImpactedFiles = getRevertImpactedResources();
+
+ pm.beginTask(lMsg, 30);
+ try {
+ doRun(pm, resourceSet, domain);
+ // Now, save all the resources
+ pm.subTask(Messages.RenameModelChange_savingResource);
+ for (Resource res : resourceSet.getResources()) {
+ if (res.getURI().isPlatformResource()) {
+ try {
+ if (res.isModified()) {
+ res.save(ResourceUtils.getSaveOptions());
+ }
+ } catch (Exception e) {
+ log.error(NLS.bind(Messages.RenameModelChange_ErrorLoading, res.getURI()), e);
+ }
+ }
+ }
+ pm.worked(5);
+
+
+ try {
+ SashModel oldSash = SashModelUtils.getSashModel(resourceSet);
+ URI oldSashURI = oldSash.getResourceURI();
+ Resource resource = oldSash.getResource();
+ resourceSet.loadModels(newFile);
+ SashModel sashModel = SashModelUtils.getSashModel(resourceSet);
+ URI stashNewFile = sashModel.getResourceURI();
+ resource.setURI(stashNewFile);
+ resource.save(ResourceUtils.getSaveOptions());
+ if(oldSash != null) { // delete old stash
+ try {
+ resourceSet.getURIConverter().delete(oldSashURI, null);
+ } catch (IOException e) {
+ log.error(Messages.bind(Messages.RenameModelChange_ErrorLoading, oldSashURI), e);
+ }
+ }
+ } catch (Exception e) {
+ log.error(e);
+ }
+
+ // Do not forget to unload all the resources to avoid memory leak
+ pm.subTask(Messages.RenameModelChange_Unloading);
+ resourceSet.unload();
+ pm.worked(1);
+
+ // Now, notify the editor of the change
+ if (!openedEditors.isEmpty()) {
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ // Get the DI file as the rename could occur on any model's file.
+ IFile newDiFile = DiModelUtils.getRelatedDiFile(newFile);
+ for (IMultiDiagramEditor editor : openedEditors) {
+ try {
+ ModelSet diRes = editor.getServicesRegistry().getService(ModelSet.class);
+ if (diRes != null) {
+ diRes.saveAs(newFile.getFullPath());
+ }
+ editor.setEditorInput(new FileEditorInput(newDiFile));
+
+ } catch (ServiceException e) {
+ log.error(e);
+ } catch (IOException e) {
+ log.error(e);
+ }
+ }
+ }
+ });
+ }
+
+ // Then, remove the old model files
+ pm.subTask(Messages.RenameModelChange_RemoveOldFile);
+ for (IResource iResource : relatedFiles) {
+ if (iResource.exists()) {
+ IPath path = iResource.getFullPath();
+ URI oldURI = getPlatformURI(path);
+ URI newURI = uriMap.get(oldURI);
+ URIConverter uriConverter = resourceSet.getURIConverter();
+ if (uriConverter.exists(newURI, Collections.EMPTY_MAP)) {
+ iResource.delete(true, new NullProgressMonitor());
+ }
+ }
+ }
+ pm.worked(4);
+
+ RenameModelChange undoChange = new RenameModelChange(newFile, oldFile, revertImpactedFiles);
+
+ if (isUndoOperation) {
+ // Restore the expected state for the basic rename change
+ newFile.move(oldFile.getFullPath(), true, new SubProgressMonitor(pm, 1));
+ }
+
+ // Invert the change
+ return undoChange;
+ } finally {
+ pm.done();
+ }
+ }
+
+ private Set<IResource> getRevertImpactedResources() {
+ Set<IResource> result = new HashSet<IResource>();
+
+ Set<IResource> relatedFiles = ModelParticipantHelpers.getRelatedFiles(oldFile);
+ relatedFiles.add(oldFile);
+
+ for (IResource initialResource : impacted) {
+ if (relatedFiles.contains(initialResource)) {
+ IResource invertedResource = invertFileName(initialResource);
+ result.add(invertedResource); // Participant model (the file is renamed)
+ } else {
+ result.add(initialResource); // Client model (only links are modified)
+ }
+ }
+
+ return result;
+ }
+
+ private IResource invertFileName(IResource initialResource) {
+ String newName;
+
+ IPath pathWithoutExtension = newFile.getFullPath().removeFileExtension();
+ IPath pathWithExtension = pathWithoutExtension.addFileExtension(initialResource.getFileExtension());
+ newName = pathWithExtension.lastSegment();
+
+ IFile newFile = oldFile.getParent().getFile(new Path(newName));
+
+ return newFile;
+ }
+
+ private RefactoringStatus manageResourceSet(final IProgressMonitor pm, final ModelSet resourceSet) {
+
+ final Collection<Resource> readOnlies = new HashSet<Resource>();
+ // for each object of the resources renamed, the refactor will search if a resource is read only or not
+ domain.getCommandStack().execute(new RecordingCommand(domain) {
+
+ @Override
+ protected void doExecute() {
+
+ // got though resources, to find if a resources that reference one of uri map is read only
+ for (URI uri : uriMap.keySet()) {
+ Resource r = resourceSet.getResource(uri, false);
+ ECrossReferenceAdapter adapter = ECrossReferenceAdapter.getCrossReferenceAdapter(resourceSet);
+ if (adapter == null) {
+ adapter = new ECrossReferenceAdapter();
+ adapter.setTarget(resourceSet);
+ }
+ if (r != null) {
+ for (Iterator<EObject> i = EcoreUtil.getAllProperContents(r, false); i.hasNext();) {
+ EObject e = i.next();
+
+ // look for all references where e is playing
+ Collection<Setting> references = adapter.getInverseReferences(e);
+ for (Setting s : references) {
+ // get the EObject that play with e
+ EObject eObject = s.getEObject();
+
+ // this is the same resource --> not interesting
+ if ((eObject.eResource() != null) && !(eObject.eResource().equals(e.eResource()))) {
+ // this is a external resource that references uri map
+ // if not not interesting
+ EStructuralFeature eFeature = s.getEStructuralFeature();
+
+ if ((!eFeature.isDerived()) && (eObject.eClass().getEAllStructuralFeatures().contains(eFeature))) {
+ if (eObject.eResource() != null && EMFHelper.isReadOnly(eObject.eResource(), domain)) {
+ boolean isWritable = EMFHelper.canMakeWritable(eObject.eResource(), domain);
+ if (isWritable) {
+ readOnlies.add(eObject.eResource());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ });
+ // if read only => error to the user
+ if (!readOnlies.isEmpty()) {
+ ReadOnlyManager readOnlyManager = new ReadOnlyManager(domain);
+ Collection<URI> uris = new ArrayList<URI>();
+ for (Iterator<Resource> iterator = readOnlies.iterator(); iterator.hasNext();) {
+ Resource r = iterator.next();
+ uris.add(r.getURI());
+ }
+
+ readOnlyManager.makeWritable(ReadOnlyAxis.anyAxis(), uris.toArray(new URI[uris.size()]));
+ }
+ return new RefactoringStatus();
+
+ }
+
+ private void doRun(final IProgressMonitor pm, final ModelSet resourceSet, final TransactionalEditingDomain domain) {
+ domain.getCommandStack().execute(new RecordingCommand(domain) {
+
+ @Override
+ protected void doExecute() {
+ // Manage Controlled map to ensure consistent history
+ // TODO change this code when history will be useless
+ URI modifiedURI = URI.createPlatformResourceURI(oldFile.getFullPath().removeFileExtension().toString(), true);
+ IModelSetQueryAdapter controledResourcesAdapter = ModelSetQuery.getExistingTypeCacheAdapter(resourceSet);
+ if (controledResourcesAdapter != null) {
+ EObject first = null;
+ for (Iterator<Notifier> i = resourceSet.getAllContents(); i.hasNext();) {
+ Notifier n = i.next();
+ if (n instanceof EObject) {
+ first = (EObject) n;
+ break;
+ }
+ }
+ if (first != null) {
+ Collection<EObject> resources = null;
+ try {
+ resources = controledResourcesAdapter.getReachableObjectsOfType(first, historyPackage.Literals.CONTROLED_RESOURCE);
+ } catch (RuntimeException e) {
+ // in case of errors integrity must be valid
+ // even performances are bad
+ resources = new LinkedList<EObject>();
+ for (int i = 0; i < resourceSet.getResources().size(); i++) {
+ Resource r = resourceSet.getResources().get(i);
+ for (Iterator<EObject> it = r.getAllContents(); it.hasNext();) {
+ EObject tmp = it.next();
+ if (tmp instanceof ControledResource) {
+ ControledResource controled = (ControledResource) tmp;
+ resources.add(controled);
+ }
+ }
+ }
+ }
+ for (EObject e : resources) {
+ if (e instanceof ControledResource) {
+ ControledResource controled = (ControledResource) e;
+ URI baseURI = URI.createURI(e.eResource().getURI().trimSegments(1).trimFragment().toString() + "/");
+ URI resolvedURI = URI.createURI(controled.getResourceURL()).resolve(baseURI);
+ if (resolvedURI.trimFileExtension().equals(modifiedURI.trimFileExtension())) {
+ String ext = resolvedURI.fileExtension();
+ URI newURL = URI.createURI(resolvedURI.trimSegments(1).toString() + "/" + newFile.getFullPath().removeFileExtension().lastSegment().toString() + "." + ext);
+ controled.setResourceURL(newURL.deresolve(baseURI).toString());
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ // Change the uri of the files
+ pm.subTask(Messages.RenameModelChange_ModifyURI);
+ for (Resource res : resourceSet.getResources()) {
+ if (res.getURI().isPlatformResource()) {
+ URI newURI = uriMap.get(res.getURI());
+ if (newURI != null) {
+ if (log.isDebugEnabled()) {
+ log.debug(NLS.bind(Messages.RenameModelChange_6, Arrays.asList(res.getURI(), newURI)));
+ }
+ res.setURI(newURI);
+ }
+ }
+
+ }
+ pm.worked(5);
+
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelParticipant.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelParticipant.java
new file mode 100644
index 00000000000..558b1b41db2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/RenameModelParticipant.java
@@ -0,0 +1,272 @@
+/*****************************************************************************
+ * Copyright (c) 2009, 2014 Atos Origin, 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:
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ * Christian W. Damus (CEA) - bug 436377
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Participant that is aware of the renaming of a model.
+ *
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
+ *
+ */
+public class RenameModelParticipant extends RenameParticipant {
+
+ private IFile fileToRename;
+
+ private IFile newFile;
+
+ private Collection<? extends IResource> impacted;
+
+ private boolean cancelled;
+
+ /**
+ * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createPreChange(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param pm
+ * The progress monitor.
+ * @return The change.
+ * @throws CoreException
+ * @throws OperationCanceledException
+ */
+
+ @Override
+ public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ return new DirtyEditorChange(fileToRename, newFile);
+ }
+
+ /**
+ * Overrides checkConditions.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
+ */
+ @Override
+ public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
+ if (cancelled) {
+ throw new OperationCanceledException();
+ }
+
+ if (isDiFile(fileToRename) && DiModel.DI_FILE_EXTENSION.equals(newFile.getFileExtension())) {
+ Collection<IResource> conflictingFiles = findConflictingFiles();
+ if (!conflictingFiles.isEmpty()) {
+ // Conflicts have been detected. Warn the user.
+
+ final String[] fileNames = new String[conflictingFiles.size()];
+
+ int i = 0;
+ for (IResource resource : conflictingFiles) {
+ fileNames[i++] = resource.getName();
+ }
+
+ String defaultMessage;
+
+ if (fileNames.length == 1) {
+ defaultMessage = "The file " + fileNames[0] + " already exists. Delete it or choose another name";
+ } else {
+ defaultMessage = "Some files alreay exist. Delete them or choose another name. Files: " + Arrays.deepToString(fileNames);
+ }
+
+ Display display = Display.getDefault();
+ if (display != null) {
+
+ RunnableWithResult<Boolean> runnable;
+ Display.getDefault().syncExec(runnable = new RunnableWithResult.Impl<Boolean>() {
+
+ public void run() {
+ setResult(false);
+ final Shell shell = Display.getDefault().getActiveShell();
+ if (shell != null) {
+ String title, message;
+
+ if (fileNames.length == 1) {
+ title = "The file " + fileNames[0] + " already exists.";
+ message = "The file " + fileNames[0] + " already exists. Do you want to delete it? (Warning: This operation cannot be undone)";
+ } else {
+ title = "Some files already exist";
+ message = "The files " + Arrays.deepToString(fileNames) + " alreay exist. Do you want to delete them? (Warning: This operation cannot be undone)";
+ }
+
+ boolean result = MessageDialog.openQuestion(shell, title, message);
+ setResult(result);
+ setStatus(Status.OK_STATUS);
+ }
+ }
+
+ });
+
+ if (runnable.getResult()) {
+ try {
+ for (IResource resource : conflictingFiles) {
+ resource.delete(true, new NullProgressMonitor());
+ impacted.remove(resource);
+ }
+ } catch (CoreException ex) {
+ // FIXME: Inconsistent state. Use a DeleteResourceChange to allow valid Undo/Redo
+ // Use preChange?
+ return RefactoringStatus.createFatalErrorStatus(ex.getMessage());
+ }
+ } else {
+ pm.setCanceled(true); // Cancel the refactoring
+ return new RefactoringStatus();
+ }
+ } else {
+ return RefactoringStatus.createFatalErrorStatus(defaultMessage);
+ }
+ }
+ }
+
+ return new RefactoringStatus();
+ }
+
+ private Collection<IResource> findConflictingFiles() {
+ List<IResource> conflictingFiles = new LinkedList<IResource>();
+
+ if (isDiFile(fileToRename)) {
+ // Check whether conflicting files exist.
+ Collection<IResource> participants = ModelParticipantHelpers.getRelatedFiles(fileToRename);
+ participants.add(fileToRename);
+ for (IResource participant : participants) {
+ IContainer parent = participant.getParent();
+ String targetName = newFile.getFullPath().removeFileExtension().addFileExtension(participant.getFileExtension()).lastSegment();
+ IFile targetFile = parent.getFile(new Path(targetName));
+ if (targetFile.exists()) {
+ conflictingFiles.add(targetFile);
+ }
+ }
+ }
+
+ return conflictingFiles;
+ }
+
+ /**
+ * Overrides createChange.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ return new RenameModelChange(fileToRename, newFile, impacted);
+ }
+
+ /**
+ * Overrides getName.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName()
+ */
+ @Override
+ public String getName() {
+ return "Papyrus Model Renaming";
+ }
+
+ /**
+ * Overrides initialize.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object)
+ */
+ @Override
+ protected boolean initialize(Object element) {
+ cancelled = false;
+
+ if (!(element instanceof IFile)) {
+ return false;
+ }
+
+ if (!isDiFile((IFile) element)) {
+ return false;
+ }
+
+ fileToRename = (IFile) element;
+ String ext = fileToRename.getFileExtension();
+
+ IContainer parent = fileToRename.getParent();
+ String newName = getArguments().getNewName();
+
+ int idx = newName.lastIndexOf('.');
+ // Do not refactor when the user remove or changes the extension: This is not a valid Papyrus model anymore
+ if (idx > 0) {
+ String extension = newName.substring(idx + 1);
+ if (!DiModel.DI_FILE_EXTENSION.equals(extension)) { // Extension changed
+ return false;
+ }
+ newName = newName.substring(0, idx);
+ } else {
+ return false; // No extension
+ }
+
+ boolean otherFiles = false;
+ for (IResource file : ModelParticipantHelpers.getRelatedFiles(fileToRename)) {
+ IPath path = file.getFullPath();
+ // Only add the change if the resource exists
+ IFile renFile = parent.getFile(path.makeRelativeTo(parent.getFullPath()));
+ if (!path.equals(fileToRename.getFullPath()) && renFile.exists()) {
+ otherFiles = true;
+ break;
+ }
+ }
+ if (otherFiles) {
+ // Get the new file
+ IPath newDiPath = fileToRename.getFullPath().removeLastSegments(1);
+ newDiPath = newDiPath.append(newName).addFileExtension(ext);
+ newFile = parent.getFile(newDiPath.makeRelativeTo(parent.getFullPath()));
+
+ try {
+ impacted = ModelParticipantHelpers.getResourceToFix(fileToRename);
+ } catch (OperationCanceledException e) {
+ cancelled = true;
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ private boolean isDiFile(IFile file) {
+ return DiModel.DI_FILE_EXTENSION.equals(file.getFileExtension());
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/messages.properties
new file mode 100644
index 00000000000..af76317fa33
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/messages.properties
@@ -0,0 +1,19 @@
+DirtyEditorChange_0=Check opened editors
+DirtyEditorChange_1=Confirm saving
+DirtyEditorChange_2=The related editor(s) must be saved to continue.
+DirtyEditorChange_3=Process can not continue if editors are not saved
+MoveModelParticipant_Name=Papyrus Model Move
+RenameModelChange_0=The resources listed are read only, the rename process can not continue :
+RenameModelChange_5=Warning
+RenameModelChange_6=Changing URI {0} into {1}
+RenameModelChange_7=The file you are renaming is opened in an editor and has unsaved changes.\nTo continue the process has to save the editor.\nDo you want to continue ?
+RenameModelChange_8=The process can not continue with an unsaved editor
+RenameModelChange_Change=Rename {0} to {1}
+RenameModelChange_DaveDirtyEditor=Saving dirty editors
+RenameModelChange_ErrorLoading=Error while loading resource {0}
+RenameModelChange_LoadingEMF=Loading EMF model into memory
+RenameModelChange_ModifyURI=Modifying resources' URI
+RenameModelChange_Name=Update all resources related to {0}
+RenameModelChange_RemoveOldFile=Removing old files
+RenameModelChange_savingResource=Saving resources
+RenameModelChange_Unloading=Unloading model
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/IScopeChooser.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/IScopeChooser.java
new file mode 100644
index 00000000000..ec12b8674b9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/IScopeChooser.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * <a href="mailto:tristan.faure@atos.net">Tristan FAURE</a> - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring.ui;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+
+
+/**
+ * Interface for elements getting related files from a file
+ *
+ * @author tfaure
+ *
+ */
+public interface IScopeChooser {
+
+ /**
+ * The name or label of the chooser
+ *
+ * @return
+ */
+ public String getName();
+
+ /**
+ * The description to inform user
+ *
+ * @return
+ */
+ public String getDescription();
+
+ /**
+ * Return the list of files related to the given parameter
+ *
+ * @param f
+ * @return
+ */
+ public List<IFile> getRelatedFiles(IFile f);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/Messages.java
new file mode 100644
index 00000000000..8b31cecd601
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/Messages.java
@@ -0,0 +1,35 @@
+package org.eclipse.papyrus.infra.ui.resources.refactoring.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.ui.resources.refactoring.ui.messages"; //$NON-NLS-1$
+
+ public static String RenameParticipantsDialog_DESCRIPTION;
+
+ public static String RenameParticipantsDialog_DESCRIPTION_LABEL;
+
+ public static String RenameParticipantsDialog_DESCRIPTION_NO_ANALYSIS;
+
+ public static String RenameParticipantsDialog_DESCRIPTION_PROJECT;
+
+ public static String RenameParticipantsDialog_DESCRIPTION_WORKSPACE;
+
+ public static String RenameParticipantsDialog_NAME_NO_ANALYSIS;
+
+ public static String RenameParticipantsDialog_NAME_PROJECT;
+
+ public static String RenameParticipantsDialog_NAME_WORKSPACE;
+
+ public static String RenameParticipantsDialog_OPTIONS;
+
+ public static String RenameParticipantsDialog_SELECT_RENAME_OPTION;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/RenameParticipantsDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/RenameParticipantsDialog.java
new file mode 100644
index 00000000000..4fa9d469d66
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/RenameParticipantsDialog.java
@@ -0,0 +1,211 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2014 Atos, 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:
+ * <a href="mailto:tristan.faure@atos.net">Tristan FAURE</a> - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ * Christian W. Damus (CEA) - bug 436377
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring.ui;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+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.papyrus.infra.ui.resources.refactoring.ui.ScopeChooser.ScopeChooserVisitor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * A dialog that asks the user to select the scope for analysis of dependent resources in a refactoring of some model resource.
+ * If the user cancels the dialog, then the initialization of the refactoring participant is cancelled and the refactoring
+ * wizard does not advance (the user may then cancel the refactoring).
+ *
+ * @author tfaure
+ *
+ */
+public class RenameParticipantsDialog extends TrayDialog {
+
+ private final IFile context;
+
+ protected IScopeChooser currentScope;
+
+ /**
+ * Create the dialog.
+ *
+ * @param parentShell
+ */
+ public RenameParticipantsDialog(Shell parentShell, IFile context) {
+ super(parentShell);
+ this.context = context;
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+
+ newShell.setText(Messages.RenameParticipantsDialog_SELECT_RENAME_OPTION);
+ }
+
+ /**
+ * Create contents of the dialog.
+ *
+ * @param parent
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite area = (Composite) super.createDialogArea(parent);
+
+ final int verticalSpace = convertVerticalDLUsToPixels(8);
+
+ Composite composite = new Composite(area, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+
+ Label blurb = new Label(composite, SWT.WRAP);
+ blurb.setText(Messages.RenameParticipantsDialog_DESCRIPTION);
+ GridData gdata = new GridData(SWT.FILL, SWT.BEGINNING, false, false, 2, 1);
+ gdata.widthHint = 250;
+ blurb.setLayoutData(gdata);
+
+ Label scopeLabel = new Label(composite, SWT.NONE);
+ scopeLabel.setText("Scope:");
+ gdata = new GridData(SWT.LEAD, SWT.BEGINNING, false, false);
+ gdata.verticalIndent = verticalSpace;
+ scopeLabel.setLayoutData(gdata);
+
+ ComboViewer comboViewer = new ComboViewer(composite, SWT.READ_ONLY);
+ comboViewer.setUseHashlookup(true);
+ comboViewer.setLabelProvider(new LabelProvider() {
+
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return true;
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IScopeChooser) {
+ IScopeChooser scope = (IScopeChooser) element;
+ return scope.getName();
+ }
+ return null;
+ }
+ });
+ comboViewer.setContentProvider(ArrayContentProvider.getInstance());
+
+ Combo combo = comboViewer.getCombo();
+ gdata = new GridData(SWT.FILL, SWT.FILL, false, false);
+ gdata.verticalIndent = verticalSpace;
+ combo.setLayoutData(gdata);
+
+ Group grpDescription = new Group(composite, SWT.NONE);
+ grpDescription.setText(Messages.RenameParticipantsDialog_DESCRIPTION_LABEL);
+ grpDescription.setLayout(new GridLayout(1, false));
+ grpDescription.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
+
+ final Text scopeDescription = new Text(grpDescription, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.READ_ONLY | SWT.V_SCROLL);
+ gdata = new GridData(SWT.FILL, SWT.FILL, false, false);
+ gdata.heightHint = convertHeightInCharsToPixels(3);
+ scopeDescription.setLayoutData(gdata);
+ scopeDescription.setText(""); //$NON-NLS-1$
+
+ // when the selection changed the description too
+ comboViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (event.getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection selec = (IStructuredSelection) event.getSelection();
+ if (selec.getFirstElement() instanceof IScopeChooser) {
+ IScopeChooser chooser = (IScopeChooser) selec.getFirstElement();
+ scopeDescription.setText(chooser.getDescription());
+ currentScope = chooser;
+ }
+ }
+ }
+ });
+ Object[] input = getInput();
+ comboViewer.setInput(input);
+ comboViewer.setSelection(new StructuredSelection(input[0]));
+
+ // We have no help for this dialog (yet)
+ setHelpAvailable(false);
+
+ return area;
+ }
+
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ /**
+ * Pre defined list of chooser maybe later an extension point will be creates
+ *
+ * @return
+ */
+ private Object[] getInput() {
+ final ScopeChooserVisitor visitor = new ScopeChooserVisitor();
+ return new IScopeChooser[] { new ScopeChooser(Messages.RenameParticipantsDialog_NAME_PROJECT, Messages.RenameParticipantsDialog_DESCRIPTION_PROJECT) {
+
+ public List<IFile> getRelatedFiles(IFile f) {
+ try {
+ f.getProject().accept(visitor, IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED);
+ return visitor.getFiles();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyList();
+ }
+ }, new ScopeChooser(Messages.RenameParticipantsDialog_NAME_WORKSPACE, Messages.RenameParticipantsDialog_DESCRIPTION_WORKSPACE) {
+
+ public List<IFile> getRelatedFiles(IFile f) {
+ try {
+ ResourcesPlugin.getWorkspace().getRoot().accept(visitor, IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED);
+ return visitor.getFiles();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyList();
+ }
+ }, new ScopeChooser(Messages.RenameParticipantsDialog_NAME_NO_ANALYSIS, Messages.RenameParticipantsDialog_DESCRIPTION_NO_ANALYSIS) {
+
+ public List<IFile> getRelatedFiles(IFile f) {
+ return Arrays.asList(f);
+ }
+ } };
+ }
+
+ public Collection<? extends IResource> getFiles() {
+ return currentScope.getRelatedFiles(context);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/ScopeChooser.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/ScopeChooser.java
new file mode 100644
index 00000000000..55cc7aafa08
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/ScopeChooser.java
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * <a href="mailto:tristan.faure@atos.net">Tristan FAURE</a> - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.resources.refactoring.ui;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
+import org.eclipse.ui.ide.IDE;
+
+
+
+/**
+ * Default Implementation of {@link IScopeChooser}
+ *
+ * @author tfaure
+ */
+public abstract class ScopeChooser implements IScopeChooser {
+
+ private final String description;
+
+ private final String label;
+
+ public ScopeChooser(String label, String formDescription) {
+ this.label = label;
+ this.description = formDescription;
+
+ }
+
+ public String getName() {
+ return label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+
+
+ public static class ScopeChooserVisitor implements IResourceVisitor {
+
+ private List<IFile> files = new LinkedList<IFile>();
+
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource instanceof IFile) {
+ IFile file = (IFile) resource;
+ if (isXMI(file)) {
+ files.add(file);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Determine if the given file is an XMI some specific code has been set for notation and di
+ *
+ * @param f
+ * @return
+ */
+ public boolean isXMI(IFile f) {
+ URI uri = URI.createPlatformResourceURI(f.getFullPath().toString(), true);
+ IContentType contentType = IDE.getContentType(f);
+ Registry instance = Resource.Factory.Registry.INSTANCE;
+ Object old = instance.getContentTypeToFactoryMap().get(Resource.Factory.Registry.DEFAULT_CONTENT_TYPE_IDENTIFIER);
+ Object old2 = instance.getExtensionToFactoryMap().get(Resource.Factory.Registry.DEFAULT_EXTENSION);
+ instance.getContentTypeToFactoryMap().put(Resource.Factory.Registry.DEFAULT_CONTENT_TYPE_IDENTIFIER, null);
+ instance.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, null);
+ boolean result = (f != null && contentType != null && (Resource.Factory.Registry.INSTANCE.getFactory(uri, contentType.getId()) != null || "notation".equals(f.getFileExtension()) || "di".equals(f.getFileExtension())));
+ instance.getContentTypeToFactoryMap().put(Resource.Factory.Registry.DEFAULT_CONTENT_TYPE_IDENTIFIER, old);
+ instance.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, old2);
+ return result;
+ }
+
+ public List<IFile> getFiles() {
+ return files;
+ }
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/messages.properties
new file mode 100644
index 00000000000..865f6b7de28
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui.resources/src/org/eclipse/papyrus/infra/ui/resources/refactoring/ui/messages.properties
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2011, 2014 Atos Origin, 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:
+# Atos Origin - Initial API and implementation
+# Christian W. Damus (CEA) - bug 436377
+#
+
+RenameParticipantsDialog_DESCRIPTION=The rename operation can affect related files that have references to elements in the renamed file. Please choose the scope of resources to analyze for references to be updated.
+RenameParticipantsDialog_DESCRIPTION_LABEL=Description
+RenameParticipantsDialog_DESCRIPTION_NO_ANALYSIS=No resources are analyzed for references. This option is discouraged except for specific advanced cases.
+RenameParticipantsDialog_DESCRIPTION_PROJECT=Resources in the project containing the renamed file will be analyzed for references.
+RenameParticipantsDialog_DESCRIPTION_WORKSPACE=All resources in the workspace will be analyzed for references. This may be a long-running operation.
+RenameParticipantsDialog_NAME_NO_ANALYSIS=No Analysis
+RenameParticipantsDialog_NAME_PROJECT=Project (default)
+RenameParticipantsDialog_NAME_WORKSPACE=Workspace
+RenameParticipantsDialog_OPTIONS=Options
+RenameParticipantsDialog_SELECT_RENAME_OPTION=Select Rename Options
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.classpath b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.gitignore b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.gitignore
new file mode 100644
index 00000000000..de5a788c8c3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.gitignore
@@ -0,0 +1,2 @@
+/.project~
+/.classpath~
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.project b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.project
new file mode 100644
index 00000000000..9943e4559d6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.infra.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.papyrus.emf.facet.common.ProjectNature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..b3aa6d60f94
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,291 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=260
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=260
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.ui.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..954281dbc31
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,68 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Papyrus
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Papyrus
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..9448f025be2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,54 @@
+Manifest-Version: 1.0
+Export-Package: org.eclipse.papyrus.infra.ui,
+ org.eclipse.papyrus.infra.ui.command,
+ org.eclipse.papyrus.infra.ui.contentoutline,
+ org.eclipse.papyrus.infra.ui.converter,
+ org.eclipse.papyrus.infra.ui.dnd,
+ org.eclipse.papyrus.infra.ui.editor,
+ org.eclipse.papyrus.infra.ui.editor.reload,
+ org.eclipse.papyrus.infra.ui.editorsfactory,
+ org.eclipse.papyrus.infra.ui.extension.commands,
+ org.eclipse.papyrus.infra.ui.extension.diagrameditor,
+ org.eclipse.papyrus.infra.ui.internal.commands;x-internal:=true,
+ org.eclipse.papyrus.infra.ui.internal.preferences;x-internal:=true,
+ org.eclipse.papyrus.infra.ui.lifecycleevents,
+ org.eclipse.papyrus.infra.ui.menu,
+ org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor,
+ org.eclipse.papyrus.infra.ui.preferences,
+ org.eclipse.papyrus.infra.ui.preferences.dialog,
+ org.eclipse.papyrus.infra.ui.providers,
+ org.eclipse.papyrus.infra.ui.services,
+ org.eclipse.papyrus.infra.ui.services.internal;x-internal:=true,
+ org.eclipse.papyrus.infra.ui.util
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .
+Bundle-Name: %pluginName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
+ org.eclipse.ui;bundle-version="3.107.0",
+ org.eclipse.core.runtime;bundle-version="3.10.0",
+ org.eclipse.core.expressions;bundle-version="3.4.600",
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.transaction,
+ com.google.guava;bundle-version="11.0.0",
+ org.eclipse.core.databinding;bundle-version="1.6.0",
+ org.eclipse.papyrus.infra.tools;bundle-version="1.2.0",
+ org.eclipse.ui.ide;bundle-version="3.12.0",
+ org.eclipse.papyrus.infra.core.sasheditor;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.core.sasheditor.di;bundle-version="1.2.0",
+ org.eclipse.emf.edit.ui;bundle-version="2.12.0",
+ org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.9.0",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.7.0",
+ org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.widgets;bundle-version="1.2.0"
+Bundle-Vendor: %providerName
+Bundle-Version: 1.2.0.qualifier
+Eclipse-BuddyPolicy: dependent
+Bundle-ManifestVersion: 2
+Bundle-Activator: org.eclipse.papyrus.infra.ui.Activator
+Bundle-Description: Plugin dedicated to manage generic menus and actions,
+ linked to EMF but not to UML nor GMF technologies.
+Bundle-SymbolicName: org.eclipse.papyrus.infra.ui;singleton:=true
+Import-Package: org.eclipse.papyrus.infra.emf.utils
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/about.html b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/about.html
new file mode 100644
index 00000000000..d35d5aed64c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/build.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/build.properties
new file mode 100644
index 00000000000..404777cc537
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .,\
+ about.html,\
+ plugin.properties,\
+ icons/,\
+ schema/
+src.includes = about.html
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/PapyrusLogo32x32.png b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/PapyrusLogo32x32.png
new file mode 100644
index 00000000000..57e441b344c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/PapyrusLogo32x32.png
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/Papyrus_32x32_t.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/Papyrus_32x32_t.gif
new file mode 100644
index 00000000000..50cd9a142ee
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/32x32/Papyrus_32x32_t.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus.gif
new file mode 100644
index 00000000000..8a31f458379
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus_16x16.gif
new file mode 100644
index 00000000000..8a31f458379
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/icons/papyrus/Papyrus_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.properties
new file mode 100644
index 00000000000..31d899f9131
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.properties
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2015, 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:
+# CEA LIST - initial API and implementation
+# Christian W. Damus - bug 485220
+#
+pluginName=Papyrus Infrastructure Base UI
+providerName=Eclipse Modeling Project
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.xml
new file mode 100644
index 00000000000..638b14b0962
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/plugin.xml
@@ -0,0 +1,533 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse version="3.0"?>
+
+<!--
+ <copyright>
+ </copyright>
+
+ $Id$
+-->
+<plugin>
+ <extension-point id="papyrusDiagram" name="PapyrusDiagram" schema="schema/papyrusDiagram.exsd"/>
+ <extension-point id="papyrusContentOutline" name="PapyrusContentOutline" schema="schema/contentOutline.exsd"/>
+
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="menu:org.eclipse.ui.main.menu?after=navigate">
+ <menu
+ id="org.eclipse.papyrus.ui.menu"
+ label="Papyrus"
+ tooltip="Papyrus Editor Menu">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </menu>
+ </menuContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+
+ <menuContribution
+ allPopups="false"
+ locationURI="menu:org.eclipse.papyrus.ui.menu">
+ <menu
+ label="&amp;Name Edition..."
+ tooltip="Quick formatting for labels">
+ <command
+ commandId="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingUpperCaseCommand"
+ label="&amp;To apply uppercase"
+ style="push">
+ <parameter
+ name="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ value="uppercase">
+ </parameter>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingLowerCaseCommand"
+ label="&amp;To apply lowercase"
+ style="push">
+ <parameter
+ name="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ value="lowercase">
+ </parameter>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingSwitchSpace2UnderscoreCommand"
+ label="&amp;To switch space and underscore"
+ style="push">
+ <parameter
+ name="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ value="switchSpace2Underscore">
+ </parameter>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingCapitalizeFirstLetterCommand"
+ label="&amp;To apply camelcase"
+ style="push">
+ <parameter
+ name="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ value="capitalizeFirstLetter">
+ </parameter>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingRemoveSpaceCommand"
+ label="&amp;To remove or add space"
+ style="push">
+ <parameter
+ name="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ value="removeSpace">
+ </parameter>
+ </command>
+ <visibleWhen
+ checkEnabled="true">
+ </visibleWhen>
+ </menu>
+ </menuContribution>
+ </extension>
+<extension
+ id="PapyrusQuickFormattingCommand"
+ name="QuickFormattingCommand"
+ point="org.eclipse.ui.commands">
+ <command
+ categoryId="org.eclipse.papyrus.infra.ui.quickformat"
+ description="The command to quickly format in uppercase the selected labels"
+ id="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingUpperCaseCommand"
+ name="Upper Case Quick Format Command">
+ <commandParameter
+ id="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ name="name"
+ optional="false">
+ </commandParameter>
+ </command>
+ <command
+ categoryId="org.eclipse.papyrus.infra.ui.quickformat"
+ description="The command to quickly format in lowercase the selected labels"
+ id="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingLowerCaseCommand"
+ name="Lower Case Quick Format Command">
+ <commandParameter
+ id="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ name="name"
+ optional="false">
+ </commandParameter>
+ </command>
+
+ <command
+ categoryId="org.eclipse.papyrus.infra.ui.quickformat"
+ description="The command to quickly format by switching space and underscore in the selected labels"
+ id="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingSwitchSpace2UnderscoreCommand"
+ name="Switch Space to Underscore Quick Format Command">
+ <commandParameter
+ id="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ name="name"
+ optional="false">
+ </commandParameter>
+ </command>
+ <command
+ categoryId="org.eclipse.papyrus.infra.ui.quickformat"
+ description="The command to quickly format by capitalizing the first letter in the selected labels"
+ id="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingCapitalizeFirstLetterCommand"
+ name="Capitalize First Letter Quick Format Command">
+ <commandParameter
+ id="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ name="name"
+ optional="false">
+ </commandParameter>
+ </command>
+ <command
+ categoryId="org.eclipse.papyrus.infra.ui.quickformat"
+ description="The command to quickly format by removing space in the selected labels"
+ id="org.eclipse.papyrus.infra.ui.menu.commands.QuickFormattingRemoveSpaceCommand"
+ name="Remove Space Quick Format Command">
+ <commandParameter
+ id="org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"
+ name="name"
+ optional="false">
+ </commandParameter>
+ </command>
+ <category
+ description="quickformat routines"
+ id="org.eclipse.papyrus.infra.ui.quickformat"
+ name="quickformat routines">
+ </category>
+</extension>
+
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="toolbar:org.eclipse.ui.main.toolbar">
+ <toolbar
+ id="org.eclipse.papyrus.ui.toolbar">
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.dropdowncommand"
+ icon="icons/papyrus/Papyrus_16x16.gif"
+ label="Close Diagrams"
+ style="pulldown"
+ tooltip="Close Current Editor&apos;s Diagrams ">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ </toolbar>
+ </menuContribution>
+ <menuContribution
+ locationURI="toolbar:org.eclipse.papyrus.ui.toolbar">
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.papyrus.infra.core.editor.ui.tabmenu?endof=tabcommands">
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closediagram"
+ label="Close Diagram"
+ style="push"
+ tooltip="Close Currently Selected Diagram">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closealldiagram"
+ label="Close All Diagrams"
+ style="push"
+ tooltip="Close All Opened Diagrams">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closeothersdiagrams"
+ label="Close Other Diagrams"
+ style="push"
+ tooltip="Close All Diagrams except the selected one">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.sasheditor.command.tabdoubleclick"
+ label="&amp;Rename Diagram"
+ style="push"
+ tooltip="Rename the diagram">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ allPopups="false"
+ locationURI="menu:org.eclipse.papyrus.infra.core.commands.dropdowncommand">
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closediagram"
+ style="push"
+ tooltip="Close Currently Selected Diagram">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closealldiagram"
+ label="Close All Diagrams"
+ style="push"
+ tooltip="Close All Opened Diagrams">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.closeothersdiagrams"
+ label="Close Other Diagrams"
+ style="push"
+ tooltip="Close All Diagrams except the selected one">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.papyrus.infra.core.commands.privatePageLayout"
+ label="Private Page Layout"
+ style="toggle"
+ tooltip="Store editor page layout privately, not shared in the DI file">
+ <visibleWhen>
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ id="org.eclipse.papyrus.infra.core.commands.closealldiagram"
+ name="Close All Diagrams">
+ </command>
+ <command
+ id="org.eclipse.papyrus.infra.core.commands.closediagram"
+ name="Close Diagram">
+ </command>
+ <command
+ id="org.eclipse.papyrus.infra.core.commands.closeothersdiagrams"
+ name="Close Other Diagrams">
+ </command>
+ <command
+ defaultHandler="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.commands.CloseDiagramCommand"
+ id="org.eclipse.papyrus.infra.core.commands.dropdowncommand"
+ name="dropdown tool">
+ </command>
+ <command
+ id="org.eclipse.papyrus.infra.core.sasheditor.command.tabdoubleclick"
+ name="Rename diagram">
+ </command>
+ <command
+ id="org.eclipse.papyrus.infra.core.commands.privatePageLayout"
+ name="Private Page Layout"
+ description="Store editor page layout privately, not shared in the DI file">
+ <state
+ id="org.eclipse.ui.commands.toggleState"
+ class="org.eclipse.papyrus.infra.ui.internal.commands.PageLayoutStorageState">
+ </state>
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.commands.CloseDiagramCommand"
+ commandId="org.eclipse.papyrus.infra.core.commands.closediagram">
+ </handler>
+ <handler
+ class="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.commands.CloseAllDiagramsCommand"
+ commandId="org.eclipse.papyrus.infra.core.commands.closealldiagram">
+ </handler>
+ <handler
+ class="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.commands.CloseOtherDiagramsCommand"
+ commandId="org.eclipse.papyrus.infra.core.commands.closeothersdiagrams">
+ </handler>
+ <handler
+ class="org.eclipse.papyrus.infra.ui.internal.commands.TogglePageLayoutStorageHandler"
+ commandId="org.eclipse.papyrus.infra.core.commands.privatePageLayout">
+ </handler>
+ </extension>
+
+ <extension
+ point="org.eclipse.papyrus.infra.core.service">
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.PageIconRegistryServiceFactory"
+ id="org.eclipse.papyrus.infra.ui.editorsfactory.IPageIconsRegistry"
+ priority="1"
+ startKind="startup">
+ </serviceFactory>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.DiSashModelManagerServiceFactory"
+ description="The concrete implementation of SashContentProviderr and IPageMngr"
+ id="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
+ </dependsOn>
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.resource.ModelSet">
+ </dependsOn>
+ </serviceFactory>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.DiSashModelMngrServiceFactory"
+ description="The concrete implementation of SashContentProviderr and IPageMngr"
+ id="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelMngr"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
+ </dependsOn>
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.resource.ModelSet">
+ </dependsOn>
+ </serviceFactory>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.PageMngrServiceFactory"
+ description="IPageMngr allows to add and remove pages to the editor."
+ id="org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageMngr"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager">
+ </dependsOn>
+ </serviceFactory>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.ContentProviderServiceFactory"
+ description="The SashContentProvider maintain the structure of pages of the editor."
+ id="org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager">
+ </dependsOn>
+ </serviceFactory>
+ <service
+ classname="org.eclipse.papyrus.infra.ui.lifecycleevents.SaveAndDirtyService"
+ description="Service used to maintain the dirty state, and to perform save and saveAs"
+ id="org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveAndDirtyService"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
+ </dependsOn>
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.resource.ModelSet">
+ </dependsOn>
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor">
+ </dependsOn>
+ </service>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.lifecycleevents.LifeCycleEventsProviderServiceFactory"
+ description="Service allowing to listen on save events."
+ id="org.eclipse.papyrus.infra.ui.lifecycleevents.ILifeCycleEventsProvider"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef=" org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveAndDirtyService">
+ </dependsOn>
+ </serviceFactory>
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.ui.editor.PageMngrServiceFactory"
+ description="IPageManager allows to add and remove pages to the editor."
+ id="org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager"
+ priority="10"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager">
+ </dependsOn>
+ </serviceFactory>
+ <service
+ classname="org.eclipse.papyrus.infra.ui.services.ResourceUpdateService"
+ id="org.eclipse.papyrus.infra.ui.services.ResourceUpdateService"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ description="This service is used to reopen the IMultiDiagramEditor when changes are detected"
+ serviceKeyRef="org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor">
+ </dependsOn>
+ </service>
+ <service
+ classname="org.eclipse.papyrus.infra.ui.services.SaveLayoutBeforeClose"
+ description="Saves the sash model when closing the editor"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.core.resource.ModelSet">
+ </dependsOn>
+ <dependsOn
+ serviceKeyRef="org.eclipse.papyrus.infra.ui.services.EditorLifecycleManager">
+ </dependsOn>
+ </service>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.exportWizards">
+ <category
+ id="org.eclipse.papyrus.infra.core.exportcategory"
+ name="Papyrus">
+ </category>
+ </extension>
+ <extension
+ point="org.eclipse.ui.importWizards">
+ <category
+ id="org.eclipse.papyrus.infra.core.importcategory"
+ name="Papyrus">
+ </category>
+ </extension>
+
+ <extension
+ point="org.eclipse.papyrus.infra.ui.papyrusContentOutline">
+ <contentoutline
+ class="org.eclipse.papyrus.infra.ui.contentoutline.NestedEditorDelegatedOutlinePage"
+ description="Generic outline for Papyrus"
+ priority="2">
+ </contentoutline>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.infra.ui.papyrusDiagram">
+ <editorDiagram
+ factoryClass="org.eclipse.papyrus.infra.ui.editorsfactory.anytype.AnyTypeEditorFactory">
+ </editorDiagram>
+ </extension>
+
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.papyrus.infra.ui.internal.preferences.EditorPreferences$Initializer">
+ </initializer>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.papyrus.infra.core.sasheditor.preferences.generalcategory"
+ class="org.eclipse.papyrus.infra.ui.internal.preferences.EditorPreferencePage"
+ id="org.eclipse.papyrus.infra.core.editorPrefs"
+ name="Editor">
+ </page>
+ </extension>
+
+ <extension
+ point="org.eclipse.core.expressions.definitions">
+ <!-- Is a Papyrus editor active that has a semantic model selection? -->
+ <definition id="org.eclipse.papyrus.ui.semanticModelActive">
+ <with
+ variable="activeEditor">
+ <adapt
+ type="org.eclipse.papyrus.infra.core.services.ServicesRegistry">
+ <test
+ property="org.eclipse.papyrus.infra.core.hasSemanticModel">
+ </test>
+ </adapt>
+ </with>
+ </definition>
+ </extension>
+</plugin>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml
new file mode 100644
index 00000000000..f6a01ae6b41
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.infra.ui</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <description>Plugin dedicated to manage generic menus and actions, linked to EMF but not to UML nor GMF technologies.</description>
+</project>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/contentOutline.exsd b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/contentOutline.exsd
new file mode 100644
index 00000000000..0b84e1af92c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/contentOutline.exsd
@@ -0,0 +1,144 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.infra.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.infra.ui" id="org.eclipse.papyrus.infra.ui.contentoutline" name="contentoutline"/>
+ </appInfo>
+ <documentation>
+ Specify the content outline to be used by the Papyrus backbone.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="contentoutline"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contentoutline">
+ <complexType>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ A human readable description.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the contentOutline.
+Class must extends org.eclipse.papyrus.ui.core.contentoutline.IPapyrusContentOutlinePage.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.infra.ui.contentoutline.IPapyrusContentOutlinePage"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="priority" type="string" use="required">
+ <annotation>
+ <documentation>
+ An integer value representing the priority of the contentOutline.
+Only one contentOutline is shown. The one with the highest priority is choosen.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="actionBarContributorId" type="string">
+ <annotation>
+ <documentation>
+ ID of the ActionBarContributor requested by the outline.
+The ID must match a declared ActionBarContributor.
+If no ID is set, use the main ActionBarContributor (the one associated to the MultiEditor).
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2008 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:
+ * CEA List - initial API and implementation
+ *******************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/papyrusDiagram.exsd b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/papyrusDiagram.exsd
new file mode 100644
index 00000000000..241fe0c27f1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/schema/papyrusDiagram.exsd
@@ -0,0 +1,342 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.infra.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.infra.ui" id="papyrusDiagram" name="Papyrus Diagram Editor"/>
+ </appInfo>
+ <documentation>
+ &lt;p&gt;
+The &lt;code&gt;org.eclipse.papyrus.infra.ui.papyrusDiagram&lt;/code&gt; extension point is used to register a new diagram editor within Papyrus. Once diagram editor is registered it can be used in the Papyrus multi-page diagram editor. The editor can have its own icon, label, a button for the creation action in the toolbar, and the possibility to be created using new Papyrus Model wizard.
+&lt;/p&gt;
+
+&lt;p&gt;Papyrus uses the term &quot;&lt;b&gt;Diagram Category&lt;/b&gt;&quot; to categorize domain models and the term &quot;&lt;b&gt;Diagram Kind&lt;/b&gt;&quot; to specialize a diagram editor for a domain model. Each Diagram Kind belongs to exactly one Diagram Category, Diagram Category can contains many Diagram Kinds. Papyrus supports &lt;b&gt;UML&lt;/b&gt;, &lt;b&gt;Profile&lt;/b&gt; and &lt;b&gt;SysML&lt;/b&gt; diagram categories.
+&lt;/p&gt;
+
+&lt;p&gt;Besides, for a given diagram category the user can specify template models - a predefined model whose content is copied into a newly created diagram. Templates can be registered using &lt;code&gt;org.eclipse.papyrus.wizards.templates&lt;/code&gt; extension point. Diagram kinds and available templates are filtered in the wizard in accordance with the chosen category. For example, if the user choses &lt;i&gt;Profile&lt;/i&gt; category, then only Profile diagram kind are available on DiagramKindPage and only ProfileWithBasicTypes template is displayed in the list of available templates.
+&lt;/p&gt;
+
+&lt;p&gt;The user is free to use the already existing diagram categories as well as implement his own.
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="editorDiagram" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="creationCommand" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="actionBarContributor" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="diagramCategory" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorDiagram">
+ <annotation>
+ <documentation>
+ A diagram editor that can be used in the Papyrus multi-page diagram editor.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="factoryClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ a name of the fully qualified class that implements &lt;samp&gt; org.eclipse.papyrus.infra.ui.extension.diagrameditor.IPluggableEditorFactory&lt;/samp&gt;. It is used to create an instance of the editor.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.infra.ui.extension.diagrameditor.IPluggableEditorFactory"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="actionBarContributorId" type="string">
+ <annotation>
+ <documentation>
+ The ID of an ActionBarContributor. If no ID is set, the main ActionBarContributor is used (the one associated to the MultiEditor).
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ a relative path of an icon used to visually represent the diagram in outline tree. The path is relative to the location of the plugin.xml file of the contributing plug-in.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="order" type="string" use="default" value="0">
+ <annotation>
+ <documentation>
+ The order of this factory. The order is used when several factories can handle the same element. An order of 0 is a very high priority, whereas an order of 50 is lower. Factories with a higher order (lower priority) can still be used e.g. via the Open with... menu
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="actionBarContributor">
+ <annotation>
+ <documentation>
+ A ActionBarContributor defines the actions for one or more editors or Views.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique identifier used as a reference for this ActionBarContributor. It is used to associate the ActionBarContributor to editors(see &lt;code&gt;actionBarContributorId&lt;/code&gt; attribute of &lt;code&gt;editorDiagram&lt;/code&gt; extension point)
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="implementingClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ a name of the fully qualified class that implements &lt;samp&gt;org.eclipse.ui.IEditorActionBarContributor&lt;/samp&gt;.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorActionBarContributor:"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="creationCommand">
+ <annotation>
+ <documentation>
+ A &quot;creationCommand&quot; is a command used to create a new diagram.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique identifier used as a reference for this creation command.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.ui.commands/command/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ a translatable name of the creation command. It is displayed in the toolbar as a button text of CreateDiagramAction, this label is also i the New Wizard while selecting the Diagram Kind.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="creationCommandClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ a name of the fully qualified class that implements &lt;samp&gt;org.eclipse.papyrus.commands.ICreationCommand&lt;/samp&gt;.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.commands.ICreationCommand"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ a relative path of an icon used to visually represent the command. The path is relative to the location of the plugin.xml file of the contributing plug-in.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="creationCondition" type="string">
+ <annotation>
+ <documentation>
+ the action in the diagram creation menu is disabled if this condition is evaluated to false.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.infra.ui.extension.commands.ICreationCondition"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ the id of a diagramCategory the creation command belongs to.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.papyrus.infra.ui.papyrusDiagram/diagramCategory/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="diagramCategory">
+ <annotation>
+ <documentation>
+ The category of a domain model. The registered category is available in New papyrus Model Wizard and it customizes creation of a domain model. It is also used to filter diagram kinds and model templates.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique identifier used as a reference for this diagram category. It is used to filter model templates and diagram kinds.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ a name of the fully qualified class that implements &lt;samp&gt;org.eclipse.papyrus.infra.ui.extension.commands.IModelCreationCommand&lt;/samp&gt;.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.infra.ui.extension.commands.IModelCreationCommand"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="extensionPrefix" type="string">
+ <annotation>
+ <documentation>
+ the file extension.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ a translatable name of the diagram category, it is displayed in the New Papyrus Model Wizard to select a Diagram Category.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ a description of the diagram category is to be displayed as a tooltip next ti its label.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ a relative path of an icon used to visually represent the diagram category. The path is relative to the location of the plugin.xml file of the contributing plug-in.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 0.7
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.papyrus.infra.ui.papyrusDiagram&quot;&gt;
+ &lt;diagramCategory
+ id=&quot;sysml&quot;
+ class=&quot;org.eclipse.papyrus.sysml.diagram.common.commands.CreateSysMLModelCommand&quot;
+ label=&quot;SysML&quot;
+ description=&quot;SysML diagrams&quot;
+ icon=&quot;icons/category_sysml.gif&quot;&gt;
+ &lt;/diagramCategory&gt;
+
+ &lt;editorDiagram
+ actionBarContributorId=&quot;org.eclipse.papyrus.uml.diagram.common.part.UMLDiagramActionBarContributor&quot;
+ factoryClass=&quot;org.eclipse.papyrus.sysml.diagram.requirement.RequirementDiagramEditorFactory&quot;
+ icon=&quot;icons/obj16/Diagram_Requirement.gif&quot;&gt;
+ &lt;/editorDiagram&gt;
+
+ &lt;creationCommand
+ id=&quot;org.eclipse.papyrus.sysml.diagram.requirement.CreateCommand&quot;
+ creationCommandClass=&quot;org.eclipse.papyrus.sysml.diagram.requirement.RequirementDiagramCreateCommand&quot;
+ icon=&quot;icons/obj16/Diagram_Requirement.gif&quot;
+ label=&quot;SysML Requirement Diagram&quot;
+ language=&quot;sysml&quot;&gt;
+ &lt;/creationCommand&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+In this example, a specific editor for SysML Requirement diagram is registered.
+Besides, a diagram category for SysML diagrams is defined, it has &lt;code&gt;sysml&lt;/code&gt; id. The category specifies a customized creation command &lt;code&gt;org.eclipse.papyrus.sysml.diagram.common.commands.CreateSysMLModelCommand&lt;/code&gt; which applies a profile to the newly-created model. In this example, the category &lt;code&gt;sysml&lt;/code&gt; containes only one diagram kind - Requirement diagram created with &lt;code&gt;org.eclipse.papyrus.sysml.diagram.requirement.CreateCommand&lt;/code&gt;, but it can be used by other diagrams as well.
+As Requirement diagram belongs to SysML category it will be created with a SysML profile applied to its root.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ &lt;p&gt;The value of the &lt;code&gt;class&lt;/code&gt; attribute of &lt;code&gt;diagramCategory&lt;/code&gt; must represent a class that implements the &lt;code&gt;org.eclipse.papyrus.infra.ui.extension.commands.IModelCreationCommand&lt;/code&gt; interface. There are a few default implementations of &lt;code&gt;IModelCreationCommand&lt;/code&gt; that may be useful to users of this extension point:
+&lt;ul&gt;
+&lt;li&gt;&lt;code&gt;org.eclipse.papyrus.commands.ModelCreationCommandBase&lt;/code&gt; - an abstract implementation of a basic &lt;code&gt;IModelCreationCommand&lt;/code&gt;.&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;org.eclipse.papyrus.uml.diagram.common.commands.CreateUMLModelCommand&lt;/code&gt;&lt;/li&gt; - implementation of IModelCreationCommand that creates a UML model.
+&lt;li&gt;&lt;code&gt;org.eclipse.papyrus.uml.diagram.profile.CreateProfileModelCommand&lt;/code&gt; - a subclass of CreateUMLModelCommand which creates Profile as a root element&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;org.eclipse.papyrus.sysml.diagram.common.commands.CreateSysMLModelCommand&lt;/code&gt; - a subclass of CreateUMLModelCommand which applies SysML profile to the root element&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/p&gt;
+
+&lt;p&gt;The value of the &lt;code&gt;creationCommandClass&lt;/code&gt; attribute of &lt;code&gt;creationCommand&lt;/code&gt;
+ must represent a class that implements the &lt;code&gt;org.eclipse.papyrus.commands.ICreationCommand&lt;/code&gt; interface.
+&lt;ul&gt;
+&lt;li&gt;&lt;code&gt;org.eclipse.papyrus.infra.gmfdiag.common.AbstractPapyrusGmfCreateDiagramCommandHandler&lt;/code&gt; - an abstract implementation of a basic &lt;code&gt;ICreationCommand&lt;/code&gt; for GMF diagrams. All CreationCommands for Papyrus diagrams extend this class.&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2008, 2010 CEA List.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made
+available under the terms of the Eclipse Public License v1.0 which accompanies
+this distribution, and is available at &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/Activator.java
new file mode 100644
index 00000000000..a744cf9db8d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/Activator.java
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ * Christian W. Damus = bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.services.spi.IContextualServiceRegistryTracker;
+import org.eclipse.papyrus.infra.tools.spi.IExecutorServiceFactory;
+import org.eclipse.papyrus.infra.ui.util.UIUtil;
+import org.eclipse.papyrus.infra.ui.util.WorkbenchPartHelper;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * 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.ui"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The plug-in's logger
+ */
+ public static LogHelper log;
+
+ private ServiceRegistration<IExecutorServiceFactory> executorFactoryReg;
+ private ServiceRegistration<IContextualServiceRegistryTracker> serviceRegistryTrackerReg;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(this);
+
+ IExecutorServiceFactory executorFactory = () -> UIUtil.createUIExecutor(Display.getDefault());
+ executorFactoryReg = context.registerService(IExecutorServiceFactory.class, executorFactory, null);
+
+ IContextualServiceRegistryTracker serviceRegistryTracker = () -> {
+ ServicesRegistry result = null;
+ IEditorPart editor = WorkbenchPartHelper.getCurrentActiveEditorPart();
+ if (editor != null) {
+ result = editor.getAdapter(ServicesRegistry.class);
+ }
+ return result;
+ };
+ serviceRegistryTrackerReg = context.registerService(IContextualServiceRegistryTracker.class, serviceRegistryTracker, null);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (serviceRegistryTrackerReg != null) {
+ serviceRegistryTrackerReg.unregister();
+ serviceRegistryTrackerReg = null;
+ }
+ if (executorFactoryReg != null) {
+ executorFactoryReg.unregister();
+ executorFactoryReg = null;
+ }
+
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractCommandHandler.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractCommandHandler.java
new file mode 100644
index 00000000000..9145151e8a0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractCommandHandler.java
@@ -0,0 +1,189 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 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:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ * Christian W. Damus (CEA) - Refactoring package/profile import/apply UI for CDO
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.command;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForHandlers;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * <pre>
+ *
+ * This abstract command handler manages:
+ * - current selection in order to build a list of the selected {@link EObject}
+ * - execute the command (returned by children) in Papyrus {@link TransactionalEditingDomain}
+ * - calculate the command enablement and visibility regarding the command executability
+ * (the command is now shown in menu if not executable).
+ *
+ * </pre>
+ */
+public abstract class AbstractCommandHandler extends AbstractPapyrusHandler {
+
+ private List<?> selection = Collections.EMPTY_LIST;
+
+ /**
+ * Returns the command to execute (to be implemented
+ * in children implementing this class)
+ *
+ * @param context
+ * the command evaluation context
+ *
+ * @return the command to execute
+ */
+ protected abstract Command getCommand(IEvaluationContext context);
+
+ protected Command getCommand(ExecutionEvent event) {
+ Command result = null;
+
+ Object context = event.getApplicationContext();
+ if (context instanceof IEvaluationContext) {
+ result = getCommand((IEvaluationContext) context);
+ } else {
+ throw new IllegalArgumentException("No evaluation context in execution event: " + event); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ protected List<?> getSelection() {
+ return selection;
+ }
+
+ /**
+ * <pre>
+ * Get the selected element, the first selected element if several are selected or null
+ * if no selection or the selection is not an {@link EObject}.
+ *
+ * @return selected {@link EObject} or null
+ * </pre>
+ *
+ */
+ protected EObject getSelectedElement() {
+ EObject eObject = null;
+
+ // Get current selection
+ List<?> selection = getSelection();
+
+ // Treat non-null selected object (try to adapt and return EObject)
+ if (!selection.isEmpty()) {
+
+ // Get first element if the selection is an IStructuredSelection
+ Object first = selection.get(0);
+
+ EObject businessObject = EMFHelper.getEObject(first);
+ if (businessObject != null) {
+ eObject = businessObject;
+ }
+ }
+
+ return eObject;
+ }
+
+ /**
+ * <pre>
+ * Parse current selection and extract the list of {@link EObject} from
+ * this selection.
+ *
+ * This also tries to adapt selected element into {@link EObject}
+ * (for example to get the {@link EObject} from a selection in the ModelExplorer).
+ *
+ * @return a list of currently selected {@link EObject}
+ * </pre>
+ *
+ */
+ protected List<EObject> getSelectedElements() {
+
+ List<EObject> selectedEObjects = new ArrayList<EObject>();
+
+ // Get current selection
+ Collection<?> selection = getSelection();
+
+ // Treat non-null selected object (try to adapt and return EObject)
+ if (!selection.isEmpty()) {
+
+ // Parse current selection
+ for (Object current : selection) {
+ // Adapt current selection to EObject
+ EObject selectedEObject = EMFHelper.getEObject(current);
+ if (selectedEObject != null) {
+ // we avoid to add null element in the list!
+ selectedEObjects.add(selectedEObject);
+ }
+ }
+ }
+
+ return selectedEObjects;
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ this.selection = (selection instanceof IStructuredSelection) ? ((IStructuredSelection) selection).toList() : Collections.EMPTY_LIST;
+
+ ServiceUtilsForHandlers.getInstance().getTransactionalEditingDomain(event).getCommandStack().execute(getCommand(event));
+ } catch (ServiceException e) {
+ Activator.log.error("Unexpected error while executing command.", e); //$NON-NLS-1$
+ } finally {
+ // clear the selection
+ this.selection = Collections.EMPTY_LIST;
+ }
+
+ return null;
+ }
+
+ protected boolean computeEnabled(IEvaluationContext context) {
+ boolean result = false;
+
+ Command command = getCommand(context);
+ if (command != null) {
+ result = command.canExecute();
+ command.dispose();
+ }
+
+ return result;
+ }
+
+ @Override
+ public void setEnabled(Object evaluationContext) {
+ if (evaluationContext instanceof IEvaluationContext) {
+ IEvaluationContext context = (IEvaluationContext) evaluationContext;
+
+ Object selection = ((IEvaluationContext) evaluationContext).getDefaultVariable();
+ if (selection instanceof Collection<?>) {
+ this.selection = (selection instanceof List<?>) ? (List<?>) selection : new java.util.ArrayList<Object>((Collection<?>) selection);
+ setBaseEnabled(computeEnabled(context));
+ this.selection = Collections.EMPTY_LIST;
+ }
+ }
+ super.setEnabled(evaluationContext);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractPapyrusHandler.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractPapyrusHandler.java
new file mode 100644
index 00000000000..d77ab4240be
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/command/AbstractPapyrusHandler.java
@@ -0,0 +1,217 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForHandlers;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForIEvaluationContext;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * This provides facilities to get the TransactionEditingDomain and the PageManager from
+ * the current Papyrus editor or view context.
+ */
+public abstract class AbstractPapyrusHandler extends AbstractHandler {
+
+ /**
+ * Obtains the transactional editing domain associated with the Papyrus Editor or View
+ * that is the context of the specified {@code execution}.
+ *
+ * @param execution
+ * an execution event
+ *
+ * @return the editing domain, or {@code null} if there is none (such as when the Papyrus Editor is closing)
+ */
+ protected TransactionalEditingDomain getEditingDomain(ExecutionEvent execution) {
+ TransactionalEditingDomain result = null;
+
+ try {
+ result = ServiceUtilsForHandlers.getInstance().getTransactionalEditingDomain(execution);
+ } catch (ServiceException e) {
+ // The wrong kind of editor/view is active or the Papyrus Editor is shutting down.
+ // These are both normal conditions
+ }
+
+ return result;
+ }
+
+ /**
+ * Obtains the transactional editing domain associated with the Papyrus Editor or View
+ * that has the specified evaluation {@code context}.
+ *
+ * @param context
+ * an evaluation context for a command's enablement or other computation
+ *
+ * @return the editing domain, or {@code null} if there is none (such as when the Papyrus Editor is closing)
+ */
+ protected TransactionalEditingDomain getEditingDomain(IEvaluationContext context) {
+ TransactionalEditingDomain result = null;
+
+ try {
+ result = ServiceUtilsForIEvaluationContext.getInstance().getTransactionalEditingDomain(context);
+ } catch (ServiceException e) {
+ // The wrong kind of editor/view is active or the Papyrus Editor is shutting down.
+ // These are both normal conditions
+ }
+
+ return result;
+ }
+
+ /**
+ * Obtains the page manager associated with the Papyrus Editor or View
+ * that is the context of the specified {@code execution}.
+ *
+ * @param execution
+ * an execution event
+ *
+ * @return the page manager, or {@code null} if there is none (such as when the Papyrus Editor is closing)
+ */
+ protected IPageManager getPageManager(ExecutionEvent execution) {
+ IPageManager result = null;
+
+ try {
+ result = ServiceUtilsForHandlers.getInstance().getIPageManager(execution);
+ } catch (ServiceException e) {
+ // The wrong kind of editor/view is active or the Papyrus Editor is shutting down.
+ // These are both normal conditions
+ }
+
+ return result;
+ }
+
+ /**
+ * Obtains the page manager associated with the Papyrus Editor or View
+ * that has the specified evaluation {@code context}.
+ *
+ * @param context
+ * an evaluation context for a command's enablement or other computation
+ *
+ * @return the page manager, or {@code null} if there is none (such as when the Papyrus Editor is closing)
+ */
+ protected IPageManager getPageManager(IEvaluationContext context) {
+ IPageManager result = null;
+
+ try {
+ result = ServiceUtilsForIEvaluationContext.getInstance().getIPageManager(context);
+ } catch (ServiceException e) {
+ // The wrong kind of editor/view is active or the Papyrus Editor is shutting down.
+ // These are both normal conditions
+ }
+
+ return result;
+ }
+
+ /**
+ * Adapt the specified object to the requested type, if possible.
+ * Return null if the object can't be adapted.
+ *
+ * @param object
+ * @param expectedClassType
+ * @return The adapted object, or null.
+ */
+ @SuppressWarnings("unchecked")
+ private <T> T adapt(Object object, Class<T> expectedClassType) {
+
+
+ EObject eobject = EMFHelper.getEObject(object);
+
+ if (eobject != null && expectedClassType.isInstance(eobject)) {
+ return (T) eobject;
+ }
+
+
+
+ // Try global mechanism
+ {
+ T ele = Platform.getAdapterManager().getAdapter(object, expectedClassType);
+ if (ele != null) {
+ return ele;
+ }
+ // Try as EObject if the expectedClasType is sub-type of EObject.
+ if (EObject.class.isAssignableFrom(expectedClassType)) {
+ // to EObject
+ eobject = Platform.getAdapterManager().getAdapter(object, EObject.class);
+
+ if (eobject != null && expectedClassType.isInstance(eobject)) {
+
+ return (T) eobject;
+ }
+ }
+ }
+ // Can't be adapted
+ return null;
+
+ }
+
+ /**
+ * Filter the list, and only retain objects that can be adapted to the specified type
+ *
+ * @param objects
+ * @param class1
+ * @return
+ */
+ private <T> List<T> getAllElementAdaptedToType(List<Object> list, Class<T> expectedClassType) {
+
+ List<T> res = new ArrayList<T>();
+
+ for (Object cur : list) {
+
+ T adapted = adapt(cur, expectedClassType);
+ if (adapted != null) {
+ res.add(adapted);
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Get all selected element of the specified type.
+ *
+ * @param expectedType
+ * @return
+ * @throws ExecutionException
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> List<T> getCurrentSelectionAdaptedToType(ExecutionEvent event, Class<T> expectedType) throws ExecutionException {
+
+ // Get selection from the workbench
+ ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
+
+ // Get the selected objects according to the type of the selected
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ return getAllElementAdaptedToType(structuredSelection.toList(), expectedType);
+ } else if (selection instanceof TreeSelection) {
+ TreeSelection treeSelection = (TreeSelection) selection;
+ return getAllElementAdaptedToType(treeSelection.toList(), expectedType);
+
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/ContentOutlineRegistry.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/ContentOutlineRegistry.java
new file mode 100644
index 00000000000..1fb84925184
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/ContentOutlineRegistry.java
@@ -0,0 +1,263 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.contentoutline;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.extension.BadClassNameException;
+import org.eclipse.papyrus.infra.core.extension.NotFoundException;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.extension.diagrameditor.EditorDescriptorExtensionFactory;
+import org.osgi.framework.Bundle;
+
+public class ContentOutlineRegistry {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusContentOutline";
+
+ private static String classAttributeName = "class";
+
+ private static String actionBarContributorIdPropertyName = "actionBarContributorId";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /**
+ * The selected content outline.
+ */
+ protected IPapyrusContentOutlinePage contentOutline;
+
+ /**
+ * Associated editor.
+ */
+ private IMultiDiagramEditor multiEditor;
+
+ /**
+ * Constructor. defaultContext, input and site are explicitly required in
+ * order be sure that they are initialized. The multiEditor should be
+ * initialized. In particular, getEditorSite(), getEditorInput() and
+ * getDefaultContext() should return initialized values.
+ *
+ * @param multiEditor
+ * @param defaultContext
+ * @param input
+ * @param site
+ * @param extensionPointNamespace
+ */
+ public ContentOutlineRegistry(IMultiDiagramEditor multiEditor, String extensionPointNamespace) {
+ this.multiEditor = multiEditor;
+ this.extensionPointNamespace = extensionPointNamespace;
+ }
+
+ /**
+ * Returns the single instance of the content outline. Creates one if
+ * necessary.
+ *
+ * @return the contentOutline the single instance of the content outline
+ * @throws BackboneException
+ * exception thrown when the outline can not be created.
+ */
+ public IPapyrusContentOutlinePage getContentOutline() throws BackboneException {
+ if (contentOutline == null) {
+ createContentOutline();
+ }
+ return contentOutline;
+ }
+
+ /**
+ * Return the {@link ContentOutlineDescriptor} with the highest priority.
+ *
+ * @return
+ * @throws BackboneException
+ * @throws NotFoundException
+ * If no ContentOutline can be found in extensions
+ */
+ private ContentOutlineDescriptor getContentOutlineDescriptor() throws BackboneException {
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+ ContentOutlineDescriptor found = null;
+
+ // look for the one with the highest priority
+ for (IConfigurationElement ele : configElements) {
+ ContentOutlineDescriptor desc = new ContentOutlineDescriptor(ele);
+ if (desc.isHigher(found)) {
+ found = desc;
+ }
+ }
+
+ // Instanciate the object
+ if (found == null) {
+ throw new NotFoundException("No ContentOutline registered."); //$NON-NLS-1$
+ }
+
+ return found;
+
+ }
+
+ /**
+ * Creates the content outline from the selected extension.
+ *
+ * @throws BackboneException
+ * exception thrown when the outline can not be created.
+ */
+ private void createContentOutline() throws BackboneException {
+
+ ContentOutlineDescriptor found = getContentOutlineDescriptor();
+ // Instanciate the object
+ if (found != null) {
+ contentOutline = found.createContentOutlinePage();
+ }
+ }
+
+ /**
+ * Inner Descriptor for content outline. This class load data from Eclipse
+ * extension mechanism TODO Change the parent class. It is here just to have
+ * quick code.
+ */
+ protected class ContentOutlineDescriptor extends EditorDescriptorExtensionFactory {
+
+ private int priority;
+
+ private String className;
+
+ private String actionBarContributorID;
+
+ private IConfigurationElement element;
+
+ /**
+ * Instance is created when requested.
+ */
+ protected IPapyrusContentOutlinePage instance = null;
+
+ /**
+ * Create a descriptor backuped by the config element.
+ */
+ protected ContentOutlineDescriptor(IConfigurationElement element) throws BackboneException {
+ String tagName = "contentoutline";
+ checkTagName(element, tagName);
+ this.className = element.getAttribute(classAttributeName);
+ this.actionBarContributorID = element.getAttribute(actionBarContributorIdPropertyName);
+ try {
+ this.priority = Integer.parseInt(element.getAttribute("priority"));
+ } catch (NumberFormatException e) {
+ this.priority = 0;
+ }
+
+ this.element = element;
+ // check parameters
+ if (className == null) {
+ throw new BadClassNameException("Class name must be set", "contentoutline", classAttributeName); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ }
+
+ /**
+ * Compare priority. The highest priority win.
+ */
+ public boolean isHigher(ContentOutlineDescriptor found) {
+ if (found == null) {
+ return true;
+ }
+ return this.getPriority() > found.getPriority();
+ }
+
+ /**
+ * Return the higher value of the descriptor. This value is used to
+ * order the contentOutline. The highest priority win.
+ */
+ private int getPriority() {
+ return priority;
+ }
+
+ /**
+ * @return the actionBarContributorID
+ */
+ public String getActionBarContributorID() {
+ return actionBarContributorID;
+ }
+
+ /**
+ * Returns the content outline page instance (lazy initialization)
+ *
+ * @return the context outline page
+ * @throws BackboneException
+ * exception thrown when a problem occurs.
+ */
+ protected IPapyrusContentOutlinePage getContentOutline() throws BackboneException {
+ if (instance == null) {
+ instance = createContentOutlinePage();
+ }
+ return instance;
+ }
+
+ /**
+ * Create the class corresponding to the class attribute.
+ */
+ private Class<IPapyrusContentOutlinePage> loadClass() throws BadClassNameException {
+ if (className == null || className.length() == 0) {
+ throw new BadClassNameException("Classname should be set.", "contentoutline", classAttributeName); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ Class<IPapyrusContentOutlinePage> factoryClass;
+ try {
+ factoryClass = (Class<IPapyrusContentOutlinePage>) Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ // try another way
+ try {
+ String declaringID = element.getContributor().getName();
+ Bundle bundle = Platform.getBundle(declaringID);
+ factoryClass = (Class<IPapyrusContentOutlinePage>) bundle.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ throw new BadClassNameException("", "contentoutline", classAttributeName, e1); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return factoryClass;
+ }
+
+ /**
+ * create the outlinepage by calling constructor without parameter and
+ * then call init method
+ *
+ * @return the outline.
+ * @throws BackboneException
+ */
+ protected IPapyrusContentOutlinePage createContentOutlinePage() throws BackboneException {
+ if (false) {
+ System.out.println("Not yet"); // FIXME : no syso
+ return null;
+ }
+ try {
+ IPapyrusContentOutlinePage outline = loadClass().newInstance();
+ outline.init(multiEditor);
+ return outline;
+
+ } catch (SecurityException e) {
+ // Lets propagate. This is an implementation problem that should
+ // be solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should
+ // be solved by programmer.
+ // throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should
+ // be solved by programmer.
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+ } // end class
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/IPapyrusContentOutlinePage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/IPapyrusContentOutlinePage.java
new file mode 100644
index 00000000000..8ce4fd3985f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/IPapyrusContentOutlinePage.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.contentoutline;
+
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+
+/**
+ * Extends the original interface to add the init method.
+ */
+public interface IPapyrusContentOutlinePage extends org.eclipse.ui.views.contentoutline.IContentOutlinePage {
+
+ /**
+ * Init the content outline.
+ *
+ * @param multiEditor
+ * the multiEditor is used to access to the context
+ * @throws BackboneException
+ * during research of the associated context.
+ */
+ void init(IMultiDiagramEditor multiEditor) throws BackboneException;
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/NestedEditorDelegatedOutlinePage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/NestedEditorDelegatedOutlinePage.java
new file mode 100644
index 00000000000..833f0ef89fb
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/contentoutline/NestedEditorDelegatedOutlinePage.java
@@ -0,0 +1,1098 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST and other.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 437217
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.contentoutline;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.papyrus.infra.core.Activator;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IEditorPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IPageLifeCycleEventsListener;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor;
+import org.eclipse.papyrus.infra.ui.editor.reload.EditorReloadEvent;
+import org.eclipse.papyrus.infra.ui.editor.reload.IEditorReloadListener;
+import org.eclipse.papyrus.infra.ui.editor.reload.IReloadContextProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.part.IPageBookViewPage;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.part.Page;
+import org.eclipse.ui.part.PageBook;
+import org.eclipse.ui.part.PageSite;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Page for Papyrus outline when active nested editor is a GMF editor
+ */
+public class NestedEditorDelegatedOutlinePage extends Page implements IPapyrusContentOutlinePage, IPageLifeCycleEventsListener, IEditorReloadListener {
+
+ /** The editor for which I am a slave. */
+ private IMultiDiagramEditor multiEditor;
+
+ /** Sash window container to listen for page changes inside the same editor */
+ private ISashWindowsContainer sashWindowsContainer;
+
+ /** Page book in which all outline controls of nested editors will be stored and displayed one by one */
+ private PageBook sashEditorPageBook;
+
+ /**
+ * Map from papyrus pages (representing nested editors) to outline page records (key type: <code>org.eclipse.papyrus.infra.core.sasheditor.editor.IPage</code>;
+ * value type: <code>OutlinePageRec</code>).
+ */
+ private Map<IPage, OutlinePageRec> mapIPapyrusPageToOutlineRec = new HashMap<IPage, OutlinePageRec>();
+
+ /**
+ * The page rec which provided the current page or <code>null</code>
+ */
+ private OutlinePageRec activeRec;
+
+ /**
+ * Default page rec that displays a simple message
+ */
+ private OutlinePageRec defaultPageRec;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(IMultiDiagramEditor multiEditor) {
+ this.multiEditor = multiEditor;
+
+ internalInit(multiEditor);
+
+ IReloadableEditor.Adapter.getAdapter(multiEditor).addEditorReloadListener(this);
+ }
+
+ private void internalInit(IMultiDiagramEditor multiEditor) {
+ sashWindowsContainer = (ISashWindowsContainer) multiEditor.getAdapter(ISashWindowsContainer.class);
+ sashWindowsContainer.addPageLifeCycleListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(IPageSite pageSite) {
+ IViewSite viewSite = getViewSite(pageSite);
+
+ DelegatedPageSite delegatedPageSite = new DelegatedPageSite(viewSite, this);
+ super.init(delegatedPageSite);
+ }
+
+ /**
+ * /**
+ * The <code>PageBookView</code> implementation of this <code>IWorkbenchPart</code> method cleans up all the pages. Subclasses
+ * may extend.
+ */
+ @Override
+ public void dispose() {
+ if (multiEditor != null) {
+ IReloadableEditor.Adapter.getAdapter(multiEditor).removeEditorReloadListener(this);
+ }
+
+ internalDispose();
+
+ multiEditor = null;
+
+ // Run super.
+ super.dispose();
+ }
+
+ private void internalDispose() {
+ // Deref all of the pages.
+ activeRec = null;
+ if (defaultPageRec != null) {
+ // check for null since the default page may not have
+ // been created (ex. perspective never visible)
+ defaultPageRec.contentOutlinePage.dispose();
+ defaultPageRec.dispose();
+ defaultPageRec = null;
+ }
+
+ java.util.List<OutlinePageRec> records = new ArrayList<NestedEditorDelegatedOutlinePage.OutlinePageRec>(mapIPapyrusPageToOutlineRec.values());
+ Iterator<OutlinePageRec> itr = records.iterator();
+ while (itr.hasNext()) {
+ OutlinePageRec rec = itr.next();
+ removePage(rec);
+ }
+
+ // remove listener and all refs to editor
+ sashWindowsContainer.removePageLifeCycleListener(this);
+ }
+
+ /**
+ * Refreshes the global actions for the active page.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected void refreshGlobalActionHandlers() {
+ // Clear old actions.
+ IActionBars bars = getSite().getActionBars();
+ bars.clearGlobalActionHandlers();
+
+ // Set new actions.
+ Map newActionHandlers = ((SubActionBars) activeRec.getPageSite().getActionBars()).getGlobalActionHandlers();
+ if (newActionHandlers != null) {
+ Set<?> keys = newActionHandlers.entrySet();
+ Iterator<?> iter = keys.iterator();
+ while (iter.hasNext()) {
+ Map.Entry<String, IAction> entry = (Map.Entry) iter.next();
+ bars.setGlobalActionHandler(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ISelection getSelection() {
+ // nothing here
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setSelection(ISelection selection) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createControl(Composite parent) {
+ sashEditorPageBook = new PageBook(parent, SWT.BORDER);
+
+ createContents();
+ }
+
+ protected void createContents() {
+ // Create the default page rec.
+ IContentOutlinePage defaultPage = createDefaultPage(sashEditorPageBook);
+ defaultPageRec = new OutlinePageRec(null, defaultPage);
+ preparePage(defaultPageRec);
+
+ // Show the initial active page or the default page
+ IPage activePage = sashWindowsContainer.getActiveSashWindowsPage();
+ if (activePage != null) {
+ OutlinePageRec rec = getOutlinePageRec(activePage);
+ if (rec == null) {
+ rec = createPage(activePage);
+ }
+
+ // Show the page, if it was successfully created
+ if (rec != null) {
+ showOutlinePageRec(rec);
+ } else {
+ showOutlinePageRec(defaultPageRec);
+ }
+ } else {
+ showOutlinePageRec(defaultPageRec);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Control getControl() {
+ return sashEditorPageBook;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageChanged(IPage newPage) {
+ // throw new UnsupportedOperationException("pageChanged not implemented " + newPage);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageOpened(IPage page) {
+ // Activator.log.debug("Opened");
+ // create the new Outline
+ // Create a page for the part.
+ OutlinePageRec rec = getOutlinePageRec(page);
+ if (rec == null) {
+ rec = createPage(page);
+ }
+
+ // Show the page, if it was successfully created
+ if (rec != null) {
+ showOutlinePageRec(rec);
+ } else {
+ showOutlinePageRec(defaultPageRec);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageClosed(IPage papyrusPage) {
+ // Activator.log.debug("Closed");
+ // Update the active part.
+ if (activeRec != null && activeRec.papyrusPage == papyrusPage) {
+ showOutlinePageRec(defaultPageRec);
+ }
+
+ // Find and remove the part page.
+ OutlinePageRec rec = getOutlinePageRec(papyrusPage);
+ if (rec != null) {
+ removePage(rec);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageActivated(IPage page) {
+ // Activator.log.debug("Activated");
+ // Create a page for the partm, if necessary.
+ OutlinePageRec rec = getOutlinePageRec(page, true);
+
+ // Show the page, if it was successfully created
+ if (rec != null) {
+ showOutlinePageRec(rec);
+ } else {
+ showOutlinePageRec(defaultPageRec);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageDeactivated(IPage page) {
+ // throw new UnsupportedOperationException("pageDeactivated not implemented " + page);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageAboutToBeOpened(IPage page) {
+ // throw new UnsupportedOperationException("pageAboutToBeOpened not implemented "+page);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void pageAboutToBeClosed(IPage page) {
+ // throw new UnsupportedOperationException("pageAboutToBeClosed not implemented " + page);
+ }
+
+ @Override
+ public void editorAboutToReload(EditorReloadEvent event) {
+ event.putContext(new OutlineContext());
+
+ internalDispose();
+ }
+
+ @Override
+ public void editorReloaded(EditorReloadEvent event) {
+ internalInit(event.getEditor());
+ createContents();
+
+ ((OutlineContext) event.getContext()).restore();
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MAINLY INSPIRED FROM PAGE BOOK VIEW
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Creates and returns the default page for this view.
+ *
+ * @param book
+ * the pagebook control
+ * @return the default page
+ */
+ protected IContentOutlinePage createDefaultPage(PageBook book) {
+ MessageOutlinePage page = new MessageOutlinePage();
+ initPage(page);
+ page.createControl(book);
+ return page;
+ }
+
+ /**
+ * Creates an outline record for a given papyrus Page. Adds it to the pagebook but does not show it.
+ *
+ * @param page
+ * The nested editor we are created an outline.
+ * @return the created outline page record
+ */
+ protected OutlinePageRec createPage(IPage papyrusPage) {
+ OutlinePageRec rec = doCreatePage(papyrusPage);
+ if (rec != null) {
+ mapIPapyrusPageToOutlineRec.put(papyrusPage, rec);
+ preparePage(rec);
+ }
+ return rec;
+ }
+
+ /**
+ * Prepares the page in the given page rec for use in this view.
+ *
+ * @param rec
+ */
+ protected void preparePage(OutlinePageRec rec) {
+ IPageSite site = null;
+
+ if (!doesPageExist(rec.contentOutlinePage)) {
+ if (rec.contentOutlinePage instanceof IPageBookViewPage) {
+ site = ((IPageBookViewPage) rec.contentOutlinePage).getSite();
+ rec.setPageSite(site);
+ }
+ }
+ }
+
+ /**
+ * Initializes the given page with a page site.
+ * <p>
+ * Subclasses should call this method after the page is created but before creating its controls.
+ * </p>
+ * <p>
+ * Subclasses may override
+ * </p>
+ *
+ * @param page
+ * The page to initialize
+ */
+ protected void initPage(IPageBookViewPage page) {
+ try {
+ IPageSite site = super.getSite();
+ // try to create a specific page site for this page
+ page.init(new PageSite(getViewSite(site)));
+ } catch (PartInitException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * @param site
+ * the page site from which parent view site is retrieved
+ * @return the retrieved page site
+ */
+ protected static IViewSite getViewSite(IPageSite site) {
+ if (site instanceof IViewSite) {
+ return ((IViewSite) site);
+ }
+ // no way to get the IViewSite from the page site.
+ if (site instanceof PageSite) {
+ try {
+ Field parentSiteField = PageSite.class.getDeclaredField("parentSite");
+ parentSiteField.setAccessible(true);
+ Object parentSite = parentSiteField.get(site);
+ if (parentSite instanceof IViewSite) {
+ return ((IViewSite) parentSite);
+ }
+ } catch (SecurityException e) {
+ Activator.log.error(e);
+ } catch (NoSuchFieldException e) {
+ Activator.log.error(e);
+ } catch (IllegalArgumentException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * Method declared on PageBookView.
+ */
+ protected OutlinePageRec doCreatePage(IPage papyrusPage) {
+ // Try to get an outline page.
+ if (papyrusPage instanceof IEditorPage) {
+ IEditorPart part = ((IEditorPage) papyrusPage).getIEditorPart();
+ Object obj = getAdapter(part, IContentOutlinePage.class, false);
+ if (obj instanceof IContentOutlinePage) {
+ IContentOutlinePage page = (IContentOutlinePage) obj;
+ if (page instanceof IPageBookViewPage) {
+ initPage((IPageBookViewPage) page);
+ }
+ page.createControl(getPageBook());
+ return new OutlinePageRec(papyrusPage, page);
+ }
+ }
+
+ // There is no content outline
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DelegatedPageSite getSite() {
+ return (DelegatedPageSite) super.getSite();
+ }
+
+ /*
+ * (non-Javadoc)
+ * Method declared on PageBookView.
+ */
+ protected void doDestroyPage(IPage papyrusPage, OutlinePageRec rec) {
+ IContentOutlinePage contentOutlinePage = rec.contentOutlinePage;
+ contentOutlinePage.dispose();
+ rec.dispose();
+ }
+
+ protected Collection<OutlinePageRec> getAllPages() {
+ return mapIPapyrusPageToOutlineRec.values();
+ }
+
+ /**
+ * Returns true if the page has already been created.
+ *
+ * @param page
+ * the page to test
+ * @return true if this page has already been created.
+ */
+ protected boolean doesPageExist(IContentOutlinePage page) {
+ return mapIPapyrusPageToOutlineRec.containsKey(page);
+ }
+
+ /**
+ * Returns the papyrus page which contributed the current outline page to this view.
+ *
+ * @return the page which contributed the current outline page or <code>null</code> if no part contributed the current page
+ */
+ protected IPage getCurrentContributingPage() {
+ if (activeRec == null) {
+ return null;
+ }
+ return activeRec.papyrusPage;
+ }
+
+ /**
+ * Returns the currently visible outline page for this view or <code>null</code> if no page is currently visible.
+ *
+ * @return the currently visible page
+ */
+ public IContentOutlinePage getCurrentOutlinePage() {
+ if (activeRec == null) {
+ return null;
+ }
+ return activeRec.contentOutlinePage;
+ }
+
+ /**
+ * Returns the view site for the given page of this view.
+ *
+ * @param page
+ * the page
+ * @return the corresponding site, or <code>null</code> if not found
+ */
+ protected IPageSite getPageSite(IPage page) {
+ OutlinePageRec rec = getOutlinePageRec(page);
+ if (rec != null) {
+ return rec.getPageSite();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the default page for this view.
+ *
+ * @return the default page
+ */
+ public IContentOutlinePage getDefaultOutlinePage() {
+ return defaultPageRec.contentOutlinePage;
+ }
+
+ /**
+ * Returns the pagebook control for this view.
+ *
+ * @return the pagebook control, or <code>null</code> if not initialized
+ */
+ protected PageBook getPageBook() {
+ return sashEditorPageBook;
+ }
+
+ /**
+ * Returns the page record for the given part.
+ *
+ * @param part
+ * the part
+ * @return the corresponding page record, or <code>null</code> if not
+ * found
+ */
+ protected OutlinePageRec getOutlinePageRec(IPage papyrusPage) {
+ return mapIPapyrusPageToOutlineRec.get(papyrusPage);
+ }
+
+ OutlinePageRec getOutlinePageRec(IPage papyrusPage, boolean create) {
+ OutlinePageRec result = getOutlinePageRec(papyrusPage);
+ if (result == null) {
+ result = createPage(papyrusPage);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the page record for the given page of this view.
+ *
+ * @param page
+ * the page
+ * @return the corresponding page record, or <code>null</code> if not
+ * found
+ */
+ protected OutlinePageRec getPageRec(IContentOutlinePage contentOutlinePage) {
+ Iterator<OutlinePageRec> itr = mapIPapyrusPageToOutlineRec.values().iterator();
+ while (itr.hasNext()) {
+ OutlinePageRec rec = itr.next();
+ if (rec.contentOutlinePage == contentOutlinePage) {
+ return rec;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Removes a page record.
+ *
+ * @param rec
+ * the page record to remove
+ */
+ protected void removePage(OutlinePageRec rec) {
+ mapIPapyrusPageToOutlineRec.remove(rec.papyrusPage);
+
+ Control control = rec.contentOutlinePage.getControl();
+ if (control != null && !control.isDisposed()) {
+ // Dispose the page's control so pages don't have to do this in their dispose method.
+ // The page's control is a child of this view's control so if this view is closed, the page's control will already be disposed.
+ control.dispose();
+ }
+
+ // Do this before destroying the page, otherwise we won't be able to retrieve the page site (it will be null)
+ IPageSite site = rec.getPageSite();
+ if (site instanceof PageSite) { // test null pointer and PageSite
+ ((SubActionBars) ((PageSite) site).getActionBars()).deactivate();
+ ((SubActionBars) ((PageSite) site).getActionBars()).dispose();
+ }
+
+ // Free the page
+ doDestroyPage(rec.papyrusPage, rec);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbenchPart.
+ */
+ @Override
+ public void setFocus() {
+ // first set focus on the page book, in case the page
+ // doesn't properly handle setFocus
+ if (sashEditorPageBook != null) {
+ sashEditorPageBook.setFocus();
+ }
+ // then set focus on the page, if any
+ if (activeRec != null) {
+ activeRec.contentOutlinePage.setFocus();
+ }
+ }
+
+ /**
+ * Shows page contained in the given page record in this view. The page
+ * record must be one from this pagebook view.
+ * <p>
+ * The <code>PageBookView</code> implementation of this method asks the pagebook control to show the given page's control, and records that the given page is now current. Subclasses may extend.
+ * </p>
+ *
+ * @param pageRec
+ * the page record containing the page to show
+ */
+ protected void showOutlinePageRec(OutlinePageRec pageRec) {
+ // If already showing do nothing
+ if (activeRec == pageRec) {
+ return;
+ }
+ // If the page is the same, just set activeRec to pageRec
+ if (activeRec != null && pageRec != null && activeRec.contentOutlinePage == pageRec.contentOutlinePage) {
+ activeRec = pageRec;
+ return;
+ }
+
+ activeRec = pageRec;
+ Control pageControl = activeRec.contentOutlinePage.getControl();
+ if (pageControl != null && !pageControl.isDisposed()) {
+ PageSite pageSite = (PageSite) activeRec.getPageSite();
+ // Verify that the page control is not disposed
+ // If we are closing, it may have already been disposed
+ sashEditorPageBook.showPage(pageControl);
+ getSite().setActivePageSite(pageSite);
+ }
+
+ }
+
+ /**
+ * If it is possible to adapt the given object to the given type, this
+ * returns the adapter. Performs the following checks:
+ *
+ * <ol>
+ * <li>Returns <code>sourceObject</code> if it is an instance of the adapter type.</li>
+ * <li>If sourceObject implements IAdaptable, it is queried for adapters.</li>
+ * <li>If sourceObject is not an instance of PlatformObject (which would have already done so), the adapter manager is queried for adapters</li>
+ * </ol>
+ *
+ * Otherwise returns null.
+ *
+ * @param sourceObject
+ * object to adapt, or null
+ * @param adapter
+ * type to adapt to
+ * @param activatePlugins
+ * true if IAdapterManager.loadAdapter should be used (may trigger plugin activation)
+ * @return a representation of sourceObject that is assignable to the
+ * adapter type, or null if no such representation exists
+ */
+ public static Object getAdapter(Object sourceObject, Class<?> adapter, boolean activatePlugins) {
+ Assert.isNotNull(adapter);
+ if (sourceObject == null) {
+ return null;
+ }
+ if (adapter.isInstance(sourceObject)) {
+ return sourceObject;
+ }
+
+ if (sourceObject instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) sourceObject;
+
+ Object result = adaptable.getAdapter(adapter);
+ if (result != null) {
+ // Sanity-check
+ Assert.isTrue(adapter.isInstance(result));
+ return result;
+ }
+ }
+
+ if (!(sourceObject instanceof PlatformObject)) {
+ Object result;
+ if (activatePlugins) {
+ result = Platform.getAdapterManager().loadAdapter(sourceObject, adapter.getName());
+ } else {
+ result = Platform.getAdapterManager().getAdapter(sourceObject, adapter);
+ }
+ if (result != null) {
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * A data structure used to store the information about the editor outline page within the papyrus outline page.
+ */
+ protected static class OutlinePageRec {
+
+ public Object subActionBars;
+
+ /** papyrus page: current editor opened as nested editor */
+ public IPage papyrusPage;
+
+ /** outline page recorded for the given papyrus page */
+ public IContentOutlinePage contentOutlinePage;
+
+ /** page site for the recorded outline page */
+ public IPageSite pageSite;
+
+ /**
+ * Creates a new page record initialized to the given papyrus page and outline page.
+ *
+ * @param papyrusPage
+ * @param contentOutlinePage
+ */
+ public OutlinePageRec(IPage papyrusPage, IContentOutlinePage contentOutlinePage) {
+ this.papyrusPage = papyrusPage;
+ this.contentOutlinePage = contentOutlinePage;
+ }
+
+ /**
+ * Sets the page site
+ *
+ * @param pageSite
+ * the page site for the recorded content outline page
+ */
+ public void setPageSite(IPageSite pageSite) {
+ this.pageSite = pageSite;
+ }
+
+ /**
+ * Sets the page site
+ *
+ * @param pageSite
+ * the page site for the recorded content outline page
+ */
+ public IPageSite getPageSite() {
+ return this.pageSite;
+ }
+
+ /**
+ * Disposes of this page record by <code>null</code>ing its fields.
+ */
+ public void dispose() {
+ papyrusPage = null;
+ contentOutlinePage = null;
+ pageSite = null;
+ }
+ }
+
+ protected static class DelegatedPageSite extends PageSite {
+
+ /** Page site of the active page in the book */
+ protected PageSite activePageSite;
+
+ private NestedEditorDelegatedOutlinePage nestedEditorDelegatedOutlinePage;
+
+ /**
+ * Constructor.
+ *
+ * @param parentViewSite
+ * @param nestedEditorDelegatedOutlinePage
+ */
+ public DelegatedPageSite(IViewSite parentViewSite, NestedEditorDelegatedOutlinePage nestedEditorDelegatedOutlinePage) {
+ super(parentViewSite);
+ this.nestedEditorDelegatedOutlinePage = nestedEditorDelegatedOutlinePage;
+ }
+
+ /**
+ * Sets the active page site
+ *
+ * @param activePageSite
+ * the activePageSite to set
+ */
+ public void setActivePageSite(PageSite activePageSite) {
+ // remove the contribution of the previous active page site
+ if (this.activePageSite != null) {
+ // update the action bars for the current page
+ getActionBars().deactivate();
+ getActionBars().clearGlobalActionHandlers();
+ getActionBars().updateActionBars();
+
+ activePageSite.deactivate();
+
+ }
+ this.activePageSite = activePageSite;
+ if (this.activePageSite != null) {
+ activePageSite.activate();
+ // update the action bars for the current page
+ getActionBars().activate();
+ getActionBars().updateActionBars();
+ }
+ }
+
+ /**
+ * Returns the active page site
+ *
+ * @return the active Page Site
+ */
+ public PageSite getActivePageSite() {
+ return activePageSite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SubActionBars getActionBars() {
+ if (activePageSite != null) {
+ return (SubActionBars) activePageSite.getActionBars();
+ }
+ return (SubActionBars) super.getActionBars();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void deactivate() {
+ // deactivate the action bars of the current active page
+ if (activePageSite != null) {
+ activePageSite.deactivate();
+ }
+
+ // deactivate all subcontributions
+ for (OutlinePageRec rec : nestedEditorDelegatedOutlinePage.getAllPages()) {
+ IPageSite site = rec.getPageSite();
+ IActionBars bars = site.getActionBars();
+ if (bars instanceof SubActionBars) {
+ SubActionBars subActionBars = (SubActionBars) bars;
+ subActionBars.deactivate();
+ subActionBars.clearGlobalActionHandlers();
+ subActionBars.updateActionBars();
+ }
+ }
+ super.deactivate();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void activate() {
+
+ // here, we have to desactivate all contributions of all pages of this delegating service.
+ // when the page site is activated, the pagebookview has already tried to update some action bars, even if it should not
+ // so we recompute all the active contributions items here, after desactivating all the contributions.
+ for (OutlinePageRec rec : nestedEditorDelegatedOutlinePage.getAllPages()) {
+ IPageSite site = rec.getPageSite();
+ IActionBars bars = site.getActionBars();
+ if (bars instanceof SubActionBars) {
+ SubActionBars subActionBars = (SubActionBars) bars;
+ subActionBars.deactivate();
+ subActionBars.clearGlobalActionHandlers();
+ subActionBars.updateActionBars();
+ }
+ }
+ if (this.activePageSite != null) {
+ activePageSite.activate();
+ // update the action bars for the current page
+ getActionBars().activate();
+ getActionBars().updateActionBars();
+ }
+ super.activate();
+ }
+ }
+
+ protected static class MessageOutlinePage implements IContentOutlinePage, IPageBookViewPage {
+
+ private Text label;
+
+ private IPageSite site;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createControl(Composite parent) {
+ label = new Text(parent, SWT.NONE);
+ label.setText("No outline for this editor");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if (label != null && label.isDisposed()) {
+ label.dispose();
+ label = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Control getControl() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setActionBars(IActionBars actionBars) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setFocus() {
+ if (label != null && label.isDisposed()) {
+ label.setFocus();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ISelection getSelection() {
+ // nothing here
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setSelection(ISelection selection) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IPageSite getSite() {
+ return site;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(IPageSite site) throws PartInitException {
+ this.site = site;
+ }
+
+ }
+
+ private class OutlineContext {
+
+ private List<PageContext> pages = Lists.newArrayListWithCapacity(mapIPapyrusPageToOutlineRec.size());
+
+ OutlineContext() {
+ for (OutlinePageRec next : mapIPapyrusPageToOutlineRec.values()) {
+ pages.add(new PageContext(next));
+ }
+ }
+
+ public void restore() {
+ for (PageContext next : pages) {
+ next.restore();
+ }
+ }
+
+ //
+ // Nested types
+ //
+
+ private class PageContext {
+
+ final URI diagramToken;
+
+ final Object context;
+
+ PageContext(OutlinePageRec outlinePage) {
+ Object diagram = outlinePage.papyrusPage.getRawModel();
+ diagramToken = (diagram instanceof EObject) ? EcoreUtil.getURI((EObject) diagram) : null;
+
+ // Can only sensibly manage restoring the state of the page if we can find it again
+ if (diagramToken == null) {
+ context = null;
+ } else {
+ IReloadContextProvider provider = AdapterUtils.adapt(outlinePage.contentOutlinePage, IReloadContextProvider.class, null);
+ context = (provider == null) ? null : provider.createReloadContext();
+ }
+ }
+
+ void restore() {
+ if (diagramToken != null) {
+ try {
+ ModelSet modelSet = multiEditor.getServicesRegistry().getService(ModelSet.class);
+
+ Object diagram = modelSet.getEObject(diagramToken, true);
+ if (diagram != null) {
+ IPage page = sashWindowsContainer.lookupModelPage(diagram);
+ if (page != null) {
+ OutlinePageRec outlinePage = getOutlinePageRec(page, true);
+ if ((outlinePage != null) && (context != null)) {
+ // Restore it. We know it adapts if it provided the reload state in the first place
+ AdapterUtils.adapt(outlinePage.contentOutlinePage, IReloadContextProvider.class, null).restore(context);
+ }
+ }
+ }
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/AbstractStringValueConverter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/AbstractStringValueConverter.java
new file mode 100644
index 00000000000..02e1f24f92c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/AbstractStringValueConverter.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * 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.ui.converter;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.messages.Messages;
+
+/**
+ * Abstract class for String value Container
+ *
+ * @author VL222926
+ *
+ */
+public abstract class AbstractStringValueConverter implements IStringValueConverter {
+
+ protected static final String THE_STRING_X_IS_NOT_VALID_TO_CREATE_Y = Messages.AbstractStringValueConverter_TheStringXIsNotValidToCreateY;
+
+ protected static final String THE_FEATURE_X_CANT_BE_RESOLVED = Messages.AbstractStringValueConverter_TheFeatureXCantBeResolved;
+
+ protected static final String THE_STRING_VALUE_X_CANT_BE_RESOLVED = Messages.AbstractStringValueConverter_TheStringValueXCantBeResolved;
+
+ protected static final String SOME_STRING_ARE_NOT_VALID_TO_CREATE_X = Messages.AbstractStringValueConverter_SomeStringsAreNotValidToCreateY;
+
+ protected static final String SOME_STRING_CANT_BE_RESOLVED_TO_FIND_X = Messages.AbstractStringValueConverter_SomeStringsCantBeResolvedToFindY;
+
+ protected static final String NO_X_REPRESENTED_BY_Y_HAVE_BEEN_FOUND = Messages.AbstractStringValueConverter_NoXReprensentedByYHaveBeenFound;
+
+ private ConvertedValueContainer<?> result;
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.ui.converter.IStringValueConverter#deduceValueFromString(java.lang.Object, java.lang.String)
+ *
+ * @param type
+ * @param valueAsString
+ * @return
+ */
+ @Override
+ public final ConvertedValueContainer<?> deduceValueFromString(final Object type, final String valueAsString) {
+ result = doDeduceValueFromString(type, valueAsString);
+ if (result == null) {
+ final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_VALUE_X_CANT_BE_RESOLVED, valueAsString));
+ result = new ConvertedValueContainer<Object>(null, status);
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ * the converted value, you should call deduceValueFromString before to call this method
+ */
+ public final ConvertedValueContainer<?> getConvertedValue() {
+ if (this.result == null) {
+ throw new IllegalStateException("You should call deduceValueFromString before to call this method"); //$NON-NLS-1$
+ }
+ return this.result;
+ }
+
+ /**
+ *
+ * @param type
+ * the type of the object
+ * @param valueAsString
+ * the string to resolve
+ * @return
+ * a {@link ConvertedValueContainer} with the resolved values and a status
+ */
+ protected abstract ConvertedValueContainer<?> doDeduceValueFromString(final Object type, final String valueAsString);
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/ConvertedValueContainer.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/ConvertedValueContainer.java
new file mode 100644
index 00000000000..657091fb03c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/ConvertedValueContainer.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * 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.ui.converter;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+
+
+/**
+ *
+ * This class allows to store the value created for a pasted String AND a result status associated to this pasted String
+ *
+ * @param <T>
+ */
+
+public class ConvertedValueContainer<T> {
+
+ /**
+ * this field is used when the pasted value is monovalued
+ */
+ private final T value;
+
+ /**
+ * the resulting status of the parsing
+ */
+ private final IStatus status;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param realValue
+ * a monovalued Value (can be <code>null</code>)
+ * @param realListValue
+ * a collection value (can be <code>null</code>)
+ * @param status
+ * a status (can be <code>null</code>)
+ */
+ public ConvertedValueContainer(final T realValue, final IStatus status) {
+ this.value = realValue;
+ this.status = status;
+ Assert.isNotNull(status);
+ }
+
+
+ /**
+ *
+ * @return
+ * the status of the conversion
+ */
+ public final IStatus getStatus() {
+ return this.status;
+ }
+
+ /**
+ *
+ * @return
+ * the value
+ */
+ public final T getConvertedValue() {
+ return this.value;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/EMFStringValueConverter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/EMFStringValueConverter.java
new file mode 100644
index 00000000000..2847e7180fa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/EMFStringValueConverter.java
@@ -0,0 +1,373 @@
+/*****************************************************************************
+ * 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.ui.converter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.emf.utils.EMFContants;
+import org.eclipse.papyrus.infra.tools.util.BooleanHelper;
+import org.eclipse.papyrus.infra.tools.util.TypesConstants;
+import org.eclipse.papyrus.infra.ui.Activator;
+
+/**
+ * Value solver for EMF
+ *
+ * WARNING : incomplete implementations
+ *
+ * @author vl222926
+ *
+ */
+
+public class EMFStringValueConverter extends AbstractStringValueConverter {
+
+
+
+ /**
+ * Context used for the resolution of the string
+ */
+ private EObject resolutionContext;
+
+ /**
+ * The separator used for multivalue
+ */
+ protected final String multiValueSeparator;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param resolutionContext
+ * the context used for the resolution of the string
+ */
+ public EMFStringValueConverter(final EObject resolutionContext, final String multiValueSeparator) {
+ this.resolutionContext = resolutionContext;
+ this.multiValueSeparator = multiValueSeparator;
+ }
+
+
+ /**
+ *
+ * @return
+ * the context to use for the resolution
+ */
+ public EObject getResolutionContext() {
+ return resolutionContext;
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ this.resolutionContext = null;
+ }
+
+ /**
+ *
+ * @param resolutionContext
+ * the table context
+ * @param feature
+ * the feature
+ * @param valueAsString
+ * the pasted string for this feature
+ * @return
+ * the value for the pasted string or <code>null</code> if not found
+ */
+ @Override
+ protected ConvertedValueContainer<?> doDeduceValueFromString(final Object feature, final String valueAsString) {
+ final EClassifier featureType = getFeatureType(feature);
+ if (feature instanceof EStructuralFeature) {
+ return deduceValueFromString(feature, featureType, valueAsString);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param feature
+ * @param featureType
+ * @param valueAsString
+ * @return
+ */
+ protected ConvertedValueContainer<?> deduceValueFromString(final Object feature, final EClassifier featureType, final String valueAsString) {
+ ConvertedValueContainer<?> realValue = null;
+ // if(feature instanceof EStructuralFeature) {
+ final int upperbound = getFeatureUpperBound(feature);
+ boolean isMany = (upperbound > 1 || upperbound == -1);
+ if (featureType instanceof EDataType) {
+ if (featureType instanceof EEnum) {
+ realValue = deduceEEnumLiteralValue((EEnum) featureType, isMany, valueAsString);
+ }
+ final String typeName = featureType.getName();
+ if (TypesConstants.STRING.equals(typeName) || EMFContants.ESTRING.equals(typeName)) {
+ realValue = deduceStringValue(isMany, valueAsString);
+ } else if (EMFContants.EBOOLEAN.equals(typeName) || TypesConstants.BOOLEAN.equals(typeName)) {
+ realValue = deduceBooleanValue(isMany, valueAsString);
+ } else if (EMFContants.EINT.equals(typeName) || TypesConstants.INTEGER.equals(typeName)) {
+ realValue = deduceIntValue(isMany, valueAsString);
+ } else if (EMFContants.EDOUBLE.equals(typeName)) {
+ realValue = deduceDoubleValue(isMany, valueAsString);
+ }
+ } else if (featureType instanceof EClass) {
+ realValue = deduceEObjectValue(getResolutionContext(), feature, (EClass) featureType, isMany, valueAsString);
+ }
+ return realValue;
+ }
+
+ protected int getFeatureUpperBound(final Object feature) {
+ return ((EStructuralFeature) feature).getUpperBound();
+ }
+
+
+
+ /**
+ *
+ * @param resolutionContext
+ * the context used for the resolution
+ * @param feature
+ * the feature
+ * @param featureType
+ * the type of the feature
+ * @param isMany
+ * <code>true</code> if the feature isMany
+ * @param valueAsString
+ * the string value to resolve
+ * @return
+ * a value container referencing the eobject represented by the string
+ * @throws StringValueSolverException
+ */
+ protected ConvertedValueContainer<?> deduceEObjectValue(EObject resolutionContext, Object feature, EClass featureType, boolean isMany, String valueAsString) {
+ if (valueAsString == null || valueAsString.equals("")) {
+ return new ConvertedValueContainer<EObject>(null, Status.OK_STATUS);
+ }
+ final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_VALUE_X_CANT_BE_RESOLVED, valueAsString));
+ return new ConvertedValueContainer<EObject>(null, status);
+ }
+
+ /**
+ *
+ * @param feature
+ * an object representing a feature
+ * @return
+ * the type of the feature
+ */
+ protected EClassifier getFeatureType(final Object feature) {
+ final EClassifier featureType;
+ if (feature instanceof EStructuralFeature) {
+ return ((EStructuralFeature) feature).getEType();
+ } else {
+ featureType = null;
+ }
+ return featureType;
+ }
+
+ /**
+ *
+ * @param eenum
+ * the enumeration
+ * @param isMany
+ * <code>true</code> if the feature is many
+ * @param valueAsString
+ * the value to convert
+ * @return
+ * the converted value
+ */
+ protected ConvertedValueContainer<?> deduceEEnumLiteralValue(final EEnum eenum, final boolean isMany, final String valueAsString) {
+ ConvertedValueContainer<?> returnedValue = null;
+ IStatus iStatus = Status.OK_STATUS;
+ final Collection<String> unresolvedValues = new ArrayList<String>();
+ if (isMany) {
+ final Collection<EEnumLiteral> values = new ArrayList<EEnumLiteral>();
+ for (final String str : valueAsString.split(this.multiValueSeparator)) {
+ final EEnumLiteral literal = eenum.getEEnumLiteral(str);
+ if (literal != null) {
+ values.add(literal);
+ } else {
+ unresolvedValues.add(str);
+ }
+ }
+ if (!unresolvedValues.isEmpty()) {
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(SOME_STRING_ARE_NOT_VALID_TO_CREATE_X, EMFContants.EENUM_LITERAL), unresolvedValues);
+ }
+ returnedValue = new MultiConvertedValueContainer<EEnumLiteral>(values, iStatus);
+ } else {
+ final EEnumLiteral literal = eenum.getEEnumLiteral(valueAsString);
+ if (literal != null) {
+ // returnedValue = new ConvertedValueContainer<EEnumLiteral>(literal, iStatus);
+ // fix a bug on enumerator
+ returnedValue = new ConvertedValueContainer<Enumerator>(literal.getInstance(), iStatus);
+ } else {
+ unresolvedValues.add(valueAsString);
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_X_IS_NOT_VALID_TO_CREATE_Y, valueAsString, EMFContants.EENUM_LITERAL), unresolvedValues);
+ returnedValue = new ConvertedValueContainer<Boolean>(null, iStatus);
+ }
+ }
+ return returnedValue;
+ }
+
+ /**
+ *
+ * @param isMany
+ * <code>true</code> if the feature isMany
+ * @param valueAsString
+ * the value to parse
+ * @return
+ * the result of the parsing
+ */
+ protected ConvertedValueContainer<?> deduceBooleanValue(final boolean isMany, final String valueAsString) {
+ ConvertedValueContainer<?> returnedValue = null;
+ IStatus iStatus = Status.OK_STATUS;
+ final Collection<String> unresolvedValues = new ArrayList<String>();
+ if (isMany) {
+ final Collection<Boolean> values = new ArrayList<Boolean>();
+ for (final String str : valueAsString.split(this.multiValueSeparator)) {
+ if (BooleanHelper.isBoolean(str)) {
+ values.add(Boolean.valueOf(valueAsString));
+ } else {
+ unresolvedValues.add(str);
+ }
+ }
+ if (!unresolvedValues.isEmpty()) {
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(SOME_STRING_ARE_NOT_VALID_TO_CREATE_X, TypesConstants.BOOLEAN), unresolvedValues);
+ }
+ returnedValue = new MultiConvertedValueContainer<Boolean>(values, iStatus);
+ } else {
+ if (BooleanHelper.isBoolean(valueAsString)) {
+ returnedValue = new ConvertedValueContainer<Boolean>(Boolean.valueOf(valueAsString), iStatus);
+ } else {
+ unresolvedValues.add(valueAsString);
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_X_IS_NOT_VALID_TO_CREATE_Y, valueAsString, TypesConstants.BOOLEAN), unresolvedValues);
+ returnedValue = new ConvertedValueContainer<Boolean>(null, iStatus);
+ }
+ }
+ return returnedValue;
+ }
+
+ /**
+ *
+ * @param isMany
+ * <code>true</code> if the feature isMany
+ * @param valueAsString
+ * the value to parse
+ * @return
+ * the result of the parsing
+ */
+ protected ConvertedValueContainer<?> deduceDoubleValue(final boolean isMany, final String valueAsString) {
+ ConvertedValueContainer<?> returnedValue = null;
+ IStatus iStatus = Status.OK_STATUS;
+ final Collection<String> unresolvedValues = new ArrayList<String>();
+ if (isMany) {
+ final Collection<Double> values = new ArrayList<Double>();
+ for (final String str : valueAsString.split(this.multiValueSeparator)) {
+ final Double value = Double.valueOf(str);
+ if (value != null) {
+ values.add(value);
+ } else {
+ unresolvedValues.add(str);
+ }
+ }
+ if (!unresolvedValues.isEmpty()) {
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(SOME_STRING_ARE_NOT_VALID_TO_CREATE_X, TypesConstants.DOUBLE), unresolvedValues);
+ }
+ returnedValue = new MultiConvertedValueContainer<Double>(values, iStatus);
+ } else {
+ try {
+ returnedValue = new ConvertedValueContainer<Double>(Double.valueOf(valueAsString), iStatus);
+ } catch (final NumberFormatException e) {
+ unresolvedValues.add(valueAsString);
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_X_IS_NOT_VALID_TO_CREATE_Y, valueAsString, TypesConstants.DOUBLE), unresolvedValues);
+ returnedValue = new ConvertedValueContainer<Boolean>(null, iStatus);
+ }
+ }
+ return returnedValue;
+ }
+
+ /**
+ *
+ * @param isMany
+ * <code>true</code> if the feature isMany
+ * @param valueAsString
+ * the value to parse
+ * @return
+ * the result of the parsing
+ */
+ protected ConvertedValueContainer<?> deduceIntValue(final boolean isMany, final String valueAsString) {
+ ConvertedValueContainer<?> returnedValue = null;
+ IStatus iStatus = Status.OK_STATUS;
+ final Collection<String> unresolvedValues = new ArrayList<String>();
+ if (isMany) {
+ final Collection<Integer> values = new ArrayList<Integer>();
+ for (final String str : valueAsString.split(this.multiValueSeparator)) {
+ try {
+ values.add(Integer.valueOf(str));
+ } catch (final NumberFormatException e) {
+ unresolvedValues.add(str);
+ }
+ }
+ if (!unresolvedValues.isEmpty()) {
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(SOME_STRING_ARE_NOT_VALID_TO_CREATE_X, TypesConstants.INTEGER), unresolvedValues);
+ }
+ returnedValue = new MultiConvertedValueContainer<Integer>(values, iStatus);
+ } else {
+ try {
+ returnedValue = new ConvertedValueContainer<Integer>(Integer.valueOf(valueAsString), iStatus);
+ } catch (final NumberFormatException e) {
+ unresolvedValues.add(valueAsString);
+ iStatus = new StringValueConverterStatus(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(THE_STRING_X_IS_NOT_VALID_TO_CREATE_Y, valueAsString, TypesConstants.INTEGER), unresolvedValues);
+ returnedValue = new ConvertedValueContainer<Boolean>(null, iStatus);
+ }
+ }
+ return returnedValue;
+ }
+
+
+ /**
+ *
+ * @param isMany
+ * <code>true</code> if the feature is many
+ * @param valueAsString
+ * the value as string
+ * @return
+ * the value container with the real value(s)
+ */
+ protected ConvertedValueContainer<?> deduceStringValue(final boolean isMany, final String valueAsString) {
+ ConvertedValueContainer<?> returnedValue = null;
+ final IStatus iStatus = Status.OK_STATUS;
+ if (isMany) {
+ final Collection<String> values = new ArrayList<String>();
+ for (final String str : valueAsString.split(this.multiValueSeparator)) {
+ values.add(str);
+ }
+ returnedValue = new MultiConvertedValueContainer<String>(values, iStatus);
+ } else {
+ returnedValue = new ConvertedValueContainer<String>(valueAsString, iStatus);
+ }
+ return returnedValue;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/IStringValueConverter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/IStringValueConverter.java
new file mode 100644
index 00000000000..5ce086d2dd7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/IStringValueConverter.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.ui.converter;
+
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * Common interface for string converter
+ *
+ * @author VL222926
+ *
+ */
+public interface IStringValueConverter extends IDisposable {
+
+ /**
+ *
+ * @param type
+ * an object representing the type of the in which we want to convert the string
+ * @param valueAsString
+ * the value represented by a string
+ * @return
+ * a {@link ConvertedValueContainer}
+ */
+ public ConvertedValueContainer<?> deduceValueFromString(final Object type, final String valueAsString);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/MultiConvertedValueContainer.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/MultiConvertedValueContainer.java
new file mode 100644
index 00000000000..4324d0191fa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/MultiConvertedValueContainer.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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.converter;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ *
+ * This class allows to store the value created for a pasted String AND a result status associated to this pasted String
+ *
+ * @param <T>
+ */
+public class MultiConvertedValueContainer<T> extends ConvertedValueContainer<Collection<T>> {
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param realValue
+ * @param status
+ */
+ public MultiConvertedValueContainer(final Collection<T> realValue, final IStatus status) {
+ super(realValue, status);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/StringValueConverterStatus.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/StringValueConverterStatus.java
new file mode 100644
index 00000000000..979bc06460c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/converter/StringValueConverterStatus.java
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * 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.ui.converter;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.Status;
+
+/**
+ * This status is used y the String Value solvers
+ *
+ * @author vl222926
+ *
+ */
+public class StringValueConverterStatus extends Status {
+
+ /**
+ * the list of the uresolved strings
+ */
+ private Collection<String> unresolvedString;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param severity
+ * the severity of the status
+ * @param pluginId
+ * the plugin id providing this status
+ * @param message
+ * the message for this status
+ * @param unresolvedString
+ * the list of the unresolved string
+ */
+ public StringValueConverterStatus(int severity, String pluginId, String message, Collection<String> unresolvedString) {
+ super(severity, pluginId, message);
+ this.unresolvedString = unresolvedString;
+ }
+
+
+ /**
+ *
+ * @return
+ * the list of the unresolved string
+ */
+ public final Collection<String> getUnresolvedString() {
+ return unresolvedString;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/dnd/PapyrusTransfer.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/dnd/PapyrusTransfer.java
new file mode 100644
index 00000000000..a31e0562b90
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/dnd/PapyrusTransfer.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation, 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:
+ * IBM Corporation - initial API and implementation
+ * Christian W. Damus - adapted from GEF for bug 469188
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.ui.dnd;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+import org.eclipse.swt.dnd.ByteArrayTransfer;
+import org.eclipse.swt.dnd.TransferData;
+
+/**
+ * A local transfer carrying a single object being dragged. Subclasses should maintain a
+ * single instance of their Transfer and provide a static method to obtain that
+ * instance.
+ */
+public abstract class PapyrusTransfer<T> extends ByteArrayTransfer {
+
+ private final Class<? extends T> objectType;
+ private final String typeName;
+ private final int typeID;
+
+ private Reference<T> object;
+ private long startTime;
+
+ protected PapyrusTransfer(Class<? extends T> objectType) {
+ super();
+
+ this.objectType = objectType;
+
+ typeName = String.format("%s:%x:%x", getClass().getSimpleName(), hashCode(), System.currentTimeMillis());
+ typeID = registerType(typeName);
+ }
+
+ @Override
+ public final int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ /**
+ * The data object is not converted to bytes. It is held onto in a field.
+ * Instead, a checksum is written out to prevent unwanted drags across
+ * mulitple running copies of Eclipse.
+ *
+ * @see org.eclipse.swt.dnd.Transfer#javaToNative(Object, TransferData)
+ */
+ @Override
+ public void javaToNative(Object object, TransferData transferData) {
+ setObject(objectType.cast(object));
+ startTime = System.currentTimeMillis();
+ if (transferData != null)
+ super.javaToNative(String.valueOf(startTime).getBytes(),
+ transferData);
+ }
+
+ /**
+ * The data object is not converted to bytes. It is held onto in a field.
+ * Instead, a checksum is written out to prevent unwanted drags across
+ * mulitple running. copies of Eclipse.
+ *
+ * @see org.eclipse.swt.dnd.Transfer#nativeToJava(TransferData)
+ */
+ @Override
+ public Object nativeToJava(TransferData transferData) {
+ byte bytes[] = (byte[]) super.nativeToJava(transferData);
+ if (bytes == null) {
+ return null;
+ }
+ long startTime = Long.parseLong(new String(bytes));
+ return (this.startTime == startTime) ? getObject() : null;
+ }
+
+ /**
+ * Obtains the object being dragged.
+ */
+ public T getObject() {
+ return (object == null) ? null : objectType.cast(object.get());
+ }
+
+ /**
+ * Sets the object being dragged.
+ */
+ public void setObject(T object) {
+ this.object = new WeakReference<>(object);
+ }
+
+ @Override
+ protected int[] getTypeIds() {
+ return new int[] { typeID };
+ }
+
+ @Override
+ protected String[] getTypeNames() {
+ return new String[] { typeName };
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/ContentProviderServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/ContentProviderServiceFactory.java
new file mode 100644
index 00000000000..49557e36432
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/ContentProviderServiceFactory.java
@@ -0,0 +1,68 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager;
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+
+/**
+ * A service factory to create the {@link ISashWindowsContentProvider} service.
+ * This service depends on {@link DiSashModelMngrServiceFactory}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class ContentProviderServiceFactory implements IServiceFactory {
+
+ /**
+ * The sashModelMangr.
+ */
+ private DiSashModelManager sashModelMngr;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ // Get required services
+ sashModelMngr = servicesRegistry.getService(DiSashModelManager.class);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
+ *
+ * @return
+ * @throws ServiceException
+ */
+ @Override
+ public Object createServiceInstance() throws ServiceException {
+ return sashModelMngr.getISashWindowsContentProvider();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java
new file mode 100644
index 00000000000..bbfb16f40a6
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java
@@ -0,0 +1,1244 @@
+/*****************************************************************************
+ * Copyright (c) 2008, 2016 LIFL, 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - manage models by URI, not IFile (CDO)
+ * Christian W. Damus (CEA) - bug 410346
+ * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up)
+ * Christian W. Damus (CEA) - bug 437217
+ * Christian W. Damus - bugs 469464, 469188, 485220
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.editor;
+
+import static org.eclipse.papyrus.infra.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.ui.URIEditorInput;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.language.ILanguageChangeListener;
+import org.eclipse.papyrus.infra.core.language.ILanguageService;
+import org.eclipse.papyrus.infra.core.language.LanguageChangeEvent;
+import org.eclipse.papyrus.infra.core.resource.ModelMultiException;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IContentChangedListener;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.AbstractMultiPageSashEditor;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager;
+import org.eclipse.papyrus.infra.core.services.ExtensionServicesRegistry;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceMultiException;
+import org.eclipse.papyrus.infra.core.services.ServiceStartKind;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.contentoutline.ContentOutlineRegistry;
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor.DirtyPolicy;
+import org.eclipse.papyrus.infra.ui.editor.reload.EditorReloadEvent;
+import org.eclipse.papyrus.infra.ui.editor.reload.IEditorReloadListener;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.IEditorInputChangedListener;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveAndDirtyService;
+import org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor.ActionBarContributorRegistry;
+import org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor.CoreComposedActionBarContributor;
+import org.eclipse.papyrus.infra.ui.services.EditorLifecycleManager;
+import org.eclipse.papyrus.infra.ui.services.internal.EditorLifecycleManagerImpl;
+import org.eclipse.papyrus.infra.ui.services.internal.InternalEditorLifecycleManager;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IGotoMarker;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Multi diagram editor allowing to plug various kind of editors. Editors are
+ * registered with the help of the Eclipse extension mechanism. This
+ * implementation allows to register editors and context separately. An editor
+ * should specify which context it need to run. This multi diagram editor allows
+ * to show editor side by side in one or more sash windows.
+ *
+ * The real implementation for the generic type T of SashMultiPageEditorPart is
+ * actually di2.Diagram
+ *
+ * @author cedric dumoulin
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
+ * Refactoring.
+ *
+ * TODO : remove GMF dependency !
+ */
+public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implements IMultiDiagramEditor, ITabbedPropertySheetPageContributor, IGotoMarker, IEditingDomainProvider {
+
+ /** ContentOutline registry */
+ private ContentOutlineRegistry contentOutlineRegistry;
+
+ /** Services registry. Used to get registered services */
+ private ServicesRegistry servicesRegistry;
+
+ /**
+ * ActionBarContributor Registry. Allows to get an ActionBar by its Id. The
+ * registry is initialized from the Eclipse extension mechanism.
+ */
+ private ActionBarContributorRegistry actionBarContributorRegistry;
+
+ /** SashModelMngr to add pages */
+ protected DiSashModelManager sashModelMngr;
+
+ /**
+ * Service used to maintain the dirty state and to perform save and saveAs.
+ */
+ protected ISaveAndDirtyService saveAndDirtyService;
+
+ private final List<IPropertySheetPage> propertiesPages = new LinkedList<IPropertySheetPage>();
+
+ private final List<Runnable> closeActions = new ArrayList<>();
+
+ /**
+ * Listener on {@link ISaveAndDirtyService#addInputChangedListener(IEditorInputChangedListener)}
+ */
+ private static class EditorInputChangedListener implements IEditorInputChangedListener {
+
+ private CoreMultiDiagramEditor editor;
+
+ public EditorInputChangedListener(CoreMultiDiagramEditor editor) {
+ this.editor = editor;
+ }
+
+ /**
+ * This method is called when the editor input is changed from the
+ * ISaveAndDirtyService.
+ *
+ * @see org.eclipse.papyrus.infra.ui.lifecycleevents.IEditorInputChangedListener#editorInputChanged(org.eclipse.ui.part.FileEditorInput)
+ *
+ * @param fileEditorInput
+ */
+ @Override
+ public void editorInputChanged(FileEditorInput fileEditorInput) {
+ // Change the editor input.
+ editor.setInputWithNotify(fileEditorInput);
+ editor.setPartName(fileEditorInput.getName());
+ }
+
+ /**
+ * The isDirty flag has changed, reflect its new value
+ *
+ * @see org.eclipse.papyrus.infra.ui.lifecycleevents.IEditorInputChangedListener#isDirtyChanged()
+ *
+ */
+ @Override
+ public void isDirtyChanged() {
+
+ // Run it in async way.
+ editor.getSite().getShell().getDisplay().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ // editor can be null if this object has been finalized, but
+ // still queued in the asyncExec queue.
+ // This can happen if the editor is disposed, but some run still in
+ // the exec queue.
+ // When the method is executed asynchronously, the object is already finalized, and so
+ // editor is null.
+ if (editor == null) {
+ return;
+ }
+ editor.firePropertyChange(IEditorPart.PROP_DIRTY);
+ }
+ });
+ }
+
+ public void dispose() {
+ this.editor = null;
+ }
+ }
+
+ protected EditorInputChangedListener editorInputChangedListener;
+
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ /**
+ * Object managing models lifeCycle.
+ */
+ protected ModelSet resourceSet;
+
+ /**
+ * Cached event that can be reused.
+ */
+ protected DoSaveEvent lifeCycleEvent;
+
+ private class ContentChangedListener implements IContentChangedListener {
+
+ /**
+ * Called when the content is changed. RefreshTabs.
+ */
+ @Override
+ public void contentChanged(ContentEvent event) {
+ scheduleRefresh();
+ }
+ }
+
+ /**
+ * A listener on model change events.
+ */
+ private ContentChangedListener contentChangedListener;
+
+ /**
+ * Undo context used to have the same undo context in all Papyrus related
+ * views and editors. TODO : move away, use a version independent of GMF,
+ * add a listener that will add the context to all commands modifying
+ * attached Resources (==> linked to ModelSet ?)
+ */
+ private IUndoContext undoContext;
+
+ /**
+ * Editor reload listeners.
+ */
+ private CopyOnWriteArrayList<IEditorReloadListener> reloadListeners = new CopyOnWriteArrayList<IEditorReloadListener>();
+
+ /**
+ * A pending reload operation (awaiting next activation of the editor).
+ */
+ private final AtomicReference<DeferredReload> pendingReload = new AtomicReference<DeferredReload>();
+
+ public CoreMultiDiagramEditor() {
+ super();
+
+ addSelfReloadListener();
+ }
+
+ /**
+ * Get the contentOutlineRegistry. Create it if needed.
+ *
+ * @return the contentOutlineRegistry
+ */
+ protected ContentOutlineRegistry getContentOutlineRegistry() {
+ if (contentOutlineRegistry == null) {
+ createContentOutlineRegistry();
+ }
+
+ return contentOutlineRegistry;
+ }
+
+ /**
+ * Create the contentOutlineRegistry.
+ */
+ private void createContentOutlineRegistry() {
+ contentOutlineRegistry = new ContentOutlineRegistry(this, Activator.PLUGIN_ID);
+ }
+
+ /**
+ * Returns the service registry associated to the editor.
+ *
+ * @return the servicesRegistry The registry.
+ */
+ @Override
+ public ServicesRegistry getServicesRegistry() {
+ if (servicesRegistry == null) {
+ servicesRegistry = createServicesRegistry();
+ }
+ return servicesRegistry;
+ }
+
+ /**
+ * Create the ServicesRegistry.
+ *
+ * @return
+ */
+ private ServicesRegistry createServicesRegistry() {
+ // Create Services Registry
+ try {
+ ServicesRegistry servicesRegistry = new ExtensionServicesRegistry(org.eclipse.papyrus.infra.core.Activator.PLUGIN_ID);
+ // servicesRegistry.startRegistry();
+ return servicesRegistry;
+ } catch (ServiceException e) {
+ // Show log and error
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Do nothing as we create the provider before any calls to this method.
+ * Should not be called by subclasses.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.editor.AbstractMultiPageSashEditor#createPageProvider()
+ */
+ @Override
+ protected ISashWindowsContentProvider createPageProvider() {
+ throw new UnsupportedOperationException("Not implemented. Should not be called as the ContentProvider is already initialized.");
+ }
+
+ /**
+ * Create the pageContentProvider.
+ *
+ * Removed since 0.10.0
+ *
+ * @param pageFactory
+ * @param diResource
+ * Resource used to load/save the SashModel.
+ *
+ *
+ */
+ // protected ISashWindowsContentProvider createPageProvider(IPageModelFactory pageFactory, Resource diResource, TransactionalEditingDomain editingDomain) {
+ //
+ // sashModelMngr = new TransactionalDiSashModelMngr(pageFactory, diResource, editingDomain);
+ //
+ // ISashWindowsContentProvider pageProvider = sashModelMngr.getISashWindowsContentProvider();
+ //
+ // return pageProvider;
+ // }
+
+ /**
+ * Get The {@link IPageMngr} used to add, open, remove or close a diagram in
+ * the SashWindow. This method is available as soon as the {@link CoreMultiDiagramEditor#init(IEditorSite, IEditorInput)} method is
+ * called.
+ *
+ * @return
+ */
+ protected IPageManager getIPageManager() throws IllegalStateException {
+ try {
+ return sashModelMngr.getIPageManager();
+ } catch (Exception e) {
+ throw new IllegalStateException("Method should be called after CoreMultiDiagramEditor#init(IEditorSite, IEditorInput) is called");
+ }
+ }
+
+ /**
+ * Get the ActionBarContributorRegistry. Creates it if necessary.
+ *
+ * @return
+ */
+ protected ActionBarContributorRegistry getActionBarContributorRegistry() {
+ if (actionBarContributorRegistry != null) {
+ return actionBarContributorRegistry;
+ }
+
+ // Try to got it from CoreComposedActionBarContributor
+ // Get it from the contributor.
+ IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
+ if (contributor instanceof CoreComposedActionBarContributor) {
+ log.debug(getClass().getSimpleName() + " - ActionBarContributorRegistry loaded from CoreComposedActionBarContributor.");
+ return ((CoreComposedActionBarContributor) contributor).getActionBarContributorRegistry();
+ } else {
+ // Create a registry.
+ log.debug(getClass().getSimpleName() + " - create an ActionBarContributorRegistry.");
+ return createActionBarContributorRegistry();
+ }
+
+ }
+
+ /**
+ * Create the ActionBarContributorRegistry.
+ *
+ * @return
+ */
+ private ActionBarContributorRegistry createActionBarContributorRegistry() {
+ return new ActionBarContributorRegistry(Activator.PLUGIN_ID);
+ }
+
+ /**
+ *
+ *
+ * @param adapter
+ *
+ * @return
+ */
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Object getAdapter(Class adapter) {
+
+ if (ServicesRegistry.class == adapter) {
+ return getServicesRegistry();
+ }
+
+ if (IPageManager.class == adapter) {
+ return getIPageManager();
+ }
+
+ if (IPropertySheetPage.class == adapter) {
+ // Do not test if tabbedPropertySheetPage is null before calling new
+ // this is managed by Eclipse which only call current method when
+ // necessary
+ return getPropertySheetPage();
+ }
+
+ // Add a viewer
+ if (IContentOutlinePage.class == adapter) {
+ try {
+ ContentOutlineRegistry outlineRegistry = getContentOutlineRegistry();
+ if (outlineRegistry == null) {
+ return null;
+ }
+ IContentOutlinePage contentOutline = outlineRegistry.getContentOutline();
+ if (contentOutline != null) {
+ return contentOutline;
+ }
+ } catch (BackboneException e) {
+ // Ignore: There is not registered outline.
+ }
+ }
+
+ if (EditingDomain.class == adapter || TransactionalEditingDomain.class == adapter) {
+ return transactionalEditingDomain;
+ }
+
+ /*
+ * Return context used for undo/redo. All papyrus views should use this
+ * context. The prefer way to get this is to use undoContext =
+ * servicesRegistry.getService(IUndoContext.class);
+ */
+ if (IUndoContext.class == adapter) {
+ return undoContext;
+ }
+
+ // EMF requirements
+ if (IEditingDomainProvider.class == adapter) {
+ return this;
+ }
+
+ if (adapter == ISelection.class) {
+ return getSite().getSelectionProvider().getSelection();
+ }
+
+ if (adapter == IReloadableEditor.class) {
+ return createReloadAdapter();
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Init the editor.
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ // Init super
+ super.init(site, input);
+
+ // Set editor name
+ setPartName(input.getName());
+
+ initContents();
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+
+ // Fire the PreDisplay event synchronously, so that listeners can continue
+ // setting up the UI before the contents are actually rendered fully
+ getLifecycleManager().firePreDisplay(this);
+
+ // Fire the PostDisplay event asynchronously, to leave time to the Eclipse
+ // framework to actually display the contents of the editor
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ // Because we are asynchronous, the editor may already have been disposed
+ // (Especially in the case of tests running in the UI Thread)
+ if (servicesRegistry == null) {
+ return;
+ }
+ getLifecycleManager().firePostDisplay(CoreMultiDiagramEditor.this);
+ }
+ });
+
+ }
+
+ protected void loadModelAndServices() throws PartInitException {
+ // Create ServicesRegistry and register services
+ servicesRegistry = createServicesRegistry();
+
+ // Add itself as a service
+ servicesRegistry.add(IMultiDiagramEditor.class, 1, this);
+
+ // Create lifeCycle event provider and the event that is used when the editor fire a save event.
+ // lifeCycleEventsProvider = new LifeCycleEventsProvider();
+ // lifeCycleEvent = new DoSaveEvent(servicesRegistry, this);
+ // servicesRegistry.add(ILifeCycleEventsProvider.class, 1, lifeCycleEventsProvider);
+
+ // register services
+ servicesRegistry.add(ActionBarContributorRegistry.class, 1, getActionBarContributorRegistry());
+ // servicesRegistry.add(TransactionalEditingDomain.class, 1, transactionalEditingDomain);
+ // servicesRegistry.add(DiResourceSet.class, 1, resourceSet);
+
+ // Create and initalize editor icons service
+ // PageIconsRegistry pageIconsRegistry = new PageIconsRegistry();
+ // PluggableEditorFactoryReader editorReader = new PluggableEditorFactoryReader(Activator.PLUGIN_ID);
+ // editorReader.populate(pageIconsRegistry);
+ // servicesRegistry.add(IPageIconsRegistry.class, 1, pageIconsRegistry);
+
+
+ // Create PageModelRegistry requested by content provider.
+ // Also populate it from extensions.
+ // PageModelFactoryRegistry pageModelRegistry = new PageModelFactoryRegistry();
+ // editorReader.populate(pageModelRegistry, servicesRegistry);
+
+ // TODO : create appropriate Resource for the contentProvider, and pass it here.
+ // This will allow to remove the old sash stuff.
+ // setContentProvider(createPageProvider(pageModelRegistry, resourceSet.getDiResource(), transactionalEditingDomain));
+ // servicesRegistry.add(ISashWindowsContentProvider.class, 1, getContentProvider());
+ // servicesRegistry.add(IPageMngr.class, 1, getIPageMngr());
+
+ // register a basic label provider
+ // adapter factory used by EMF objects
+ AdapterFactory factory = null;
+ try {
+ EditingDomain domain = ServiceUtils.getInstance().getTransactionalEditingDomain(servicesRegistry);
+ if (domain instanceof AdapterFactoryEditingDomain) {
+ // Use the adapter factory already provided by this editing domain
+ factory = ((AdapterFactoryEditingDomain) domain).getAdapterFactory();
+ }
+ } catch (ServiceException e) {
+ // OK, there's no editing domain. That's fine
+ }
+
+ if (factory == null) {
+ // Must create a new adapter factory
+ factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+ }
+
+ /** label provider for EMF objects */
+ ILabelProvider labelProvider = new AdapterFactoryLabelProvider(factory) {
+
+ /**
+ * This implements {@link ILabelProvider}.getText by forwarding it
+ * to an object that implements {@link IItemLabelProvider#getText
+ * IItemLabelProvider.getText}
+ */
+ @Override
+ public String getText(Object object) {
+ // Get the adapter from the factory.
+ //
+ IItemLabelProvider itemLabelProvider = (IItemLabelProvider) adapterFactory.adapt(object, IItemLabelProvider.class);
+ if (object instanceof EObject) {
+ if (((EObject) object).eIsProxy()) {
+ return "Proxy - " + object;
+ }
+ }
+ return itemLabelProvider != null ? itemLabelProvider.getText(object) : object == null ? "" : object.toString();
+ }
+ };
+ servicesRegistry.add(ILabelProvider.class, 1, labelProvider);
+
+ EditorLifecycleManager lifecycleManager = new EditorLifecycleManagerImpl();
+ servicesRegistry.add(EditorLifecycleManager.class, 1, lifecycleManager, ServiceStartKind.LAZY);
+
+ // Start servicesRegistry
+ URI uri;
+ IEditorInput input = getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ uri = URI.createPlatformResourceURI(((IFileEditorInput) input).getFile().getFullPath().toString(), true);
+ } else if (input instanceof URIEditorInput) {
+ uri = ((URIEditorInput) input).getURI();
+ } else {
+ uri = URI.createURI(((IURIEditorInput) input).getURI().toString());
+ }
+
+ try {
+ // Start the ModelSet first, and load if from the specified File.
+ // Also start me so that I may be retrieved from the registry by other services
+ List<Class<?>> servicesToStart = new ArrayList<Class<?>>(1);
+ servicesToStart.add(ModelSet.class);
+ servicesToStart.add(IMultiDiagramEditor.class);
+
+ servicesRegistry.startServicesByClassKeys(servicesToStart);
+
+ resourceSet = servicesRegistry.getService(ModelSet.class);
+ resourceSet.loadModels(uri);
+
+ // start remaining services
+ servicesRegistry.startRegistry();
+ } catch (ModelMultiException e) {
+ try {
+ // with the ModelMultiException it is still possible to open the
+ // editors that's why the service registry is still started
+ servicesRegistry.startRegistry();
+ warnUser(e);
+ } catch (ServiceException e1) {
+ log.error(e);
+ // throw new PartInitException("could not initialize services", e); //$NON-NLS-1$
+ }
+ } catch (ServiceException e) {
+ log.error(e);
+ // throw new PartInitException("could not initialize services", e);
+ }
+
+
+ // Get required services
+
+ try {
+ transactionalEditingDomain = servicesRegistry.getService(TransactionalEditingDomain.class);
+ sashModelMngr = servicesRegistry.getService(DiSashModelManager.class);
+
+ saveAndDirtyService = servicesRegistry.getService(ISaveAndDirtyService.class);
+ undoContext = servicesRegistry.getService(IUndoContext.class);
+
+ servicesRegistry.getService(ILanguageService.class).addLanguageChangeListener(createLanguageChangeListener());
+ } catch (ServiceException e) {
+ log.error("A required service is missing.", e);
+ // if one of the services above fail to start, the editor can't run
+ // => stop
+ throw new PartInitException("could not initialize services", e);
+ }
+
+
+ // Listen on input changed from the ISaveAndDirtyService
+ editorInputChangedListener = new EditorInputChangedListener(this);
+ saveAndDirtyService.addInputChangedListener(editorInputChangedListener);
+ getLifecycleManager().firePostInit(this);
+ }
+
+ private ILanguageChangeListener createLanguageChangeListener() {
+ return new ILanguageChangeListener() {
+
+ @Override
+ public void languagesChanged(LanguageChangeEvent event) {
+ // Re-load the editor if languages changed, because new ModelSet configurations may be required
+ if (event.getType() == LanguageChangeEvent.ADDED) {
+ new UIJob(getSite().getShell().getDisplay(), NLS.bind("Reload editor {0}", getTitle())) {
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ IStatus result = Status.OK_STATUS;
+ monitor = SubMonitor.convert(monitor, IProgressMonitor.UNKNOWN);
+
+ try {
+ ISashWindowsContainer container = getISashWindowsContainer();
+ if ((container != null) && !container.isDisposed()) {
+ IReloadableEditor.ReloadReason reason = IReloadableEditor.ReloadReason.RESOURCES_CHANGED;
+
+ DirtyPolicy dirtyPolicy = DirtyPolicy.getDefault();
+ try {
+ IReloadableEditor.Adapter.getAdapter(CoreMultiDiagramEditor.this).reloadEditor(resourceSet.getResources(), reason, dirtyPolicy);
+ } catch (CoreException e) {
+ result = e.getStatus();
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+
+ return result;
+ }
+ }.schedule();
+ }
+ }
+ };
+ }
+
+ private InternalEditorLifecycleManager getLifecycleManager() {
+ // I've been disposed
+ if (servicesRegistry == null) {
+ return null;
+ }
+ try {
+ return (InternalEditorLifecycleManager) servicesRegistry.getService(EditorLifecycleManager.class);
+ } catch (ServiceException ex) {
+ Activator.log.error(ex);
+ }
+ return null;
+ }
+
+ protected void loadNestedEditors() throws PartInitException {
+ ISashWindowsContentProvider contentProvider = null;
+ try {
+ contentProvider = servicesRegistry.getService(ISashWindowsContentProvider.class);
+ } catch (ServiceException ex) {
+ log.error("A required service is missing.", ex);
+ // if one of the services above fail to start, the editor can't run
+ // => stop
+ throw new PartInitException("could not initialize services", ex);
+ }
+
+ // Set the content provider providing editors.
+ setContentProvider(contentProvider);
+
+ // Listen on contentProvider changes
+ if (contentChangedListener == null) {
+ contentChangedListener = new ContentChangedListener();
+ }
+ sashModelMngr.getSashModelContentChangedProvider().addListener(contentChangedListener);
+
+ IEditorInput input = getEditorInput();
+
+ if (input instanceof IPapyrusPageInput) {
+ IPapyrusPageInput papyrusPageInput = (IPapyrusPageInput) input;
+ final IPageManager pageManager = getIPageManager();
+
+ if (papyrusPageInput.closeOtherPages()) {
+ pageManager.closeAllOpenedPages();
+ }
+
+ for (URI pageIdentifierURI : papyrusPageInput.getPages()) {
+ final EObject pageIdentifier = resourceSet.getEObject(pageIdentifierURI, true);
+ if (!pageManager.allPages().contains(pageIdentifier)) {
+ Activator.log.warn("The object " + pageIdentifier + " does not reference an existing page");
+ continue;
+ }
+
+ if (pageManager.isOpen(pageIdentifier)) {
+ pageManager.selectPage(pageIdentifier);
+ } else {
+ pageManager.openPage(pageIdentifier);
+ }
+ }
+ }
+ }
+
+ protected void warnUser(ModelMultiException e) {
+ Activator.log.error(e);
+ MessageDialog.openError(getSite().getShell(), "Error", String.format("Your model is corrupted, invalid links have been found :\n" + "%s" + "It is recommended to fix it before editing it", e.getMessage()));
+ }
+
+ /**
+ * Activate this editor. Called after the SWT.control is created.
+ */
+ @Override
+ protected void activate() {
+ super.activate();
+
+ initFolderTabMenus();
+
+ try {
+ // Register ISashWindowsContainer as service
+ // Should be done only once the container is ready.
+ getServicesRegistry().add(ISashWindowsContainer.class, 1, getISashWindowsContainer());
+ getServicesRegistry().startServicesByClassKeys(ISashWindowsContainer.class);
+ // Let the IPageMngr use the ISashWindowsContainer to discover current folder
+ // This should be done after SashWindowContainer initialization.
+ // DiSashModelManager sashModelManager = getServicesRegistry().getService(DiSashModelManager.class);
+ sashModelMngr.setCurrentFolderAndPageMngr(getISashWindowsContainer());
+
+ } catch (ServiceException e) {
+ log.error(e);
+ }
+
+ }
+
+ /**
+ * Init the contextual menu shown in the folder tabs. This popup menu is
+ * contributed by the help of Eclipse extensions, using the Commands
+ * framework. I.e, to add a menu item, create a menu, a command and an
+ * handler in the extension.
+ */
+ protected void initFolderTabMenus() {
+ ISashWindowsContainer container = getISashWindowsContainer();
+
+ // TODO : use a constant
+ MenuManager menuManager = new MenuManager("tabmenu");
+ menuManager.add(new Separator("tabcommands"));
+ menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ container.setFolderTabMenuManager(menuManager);
+
+ // TODO : use a constant
+ getSite().registerContextMenu("org.eclipse.papyrus.infra.core.editor.ui.tabmenu", menuManager, getSite().getSelectionProvider());
+
+ }
+
+ /**
+ * Overrides getPropertySheetPage.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor#getPropertySheetPage()
+ */
+ public IPropertySheetPage getPropertySheetPage() {
+ IPropertySheetPage propertiesPage = new MultiDiagramPropertySheetPage(this);
+ propertiesPages.add(propertiesPage);
+ return propertiesPage;
+ }
+
+ @Override
+ public void dispose() {
+ for (IPropertySheetPage propertiesPage : this.propertiesPages) {
+ propertiesPage.dispose();
+ }
+ propertiesPages.clear();
+
+ // Forget the outline page(s)
+ contentOutlineRegistry = null;
+
+ super.dispose();
+ }
+
+ private IReloadableEditor createReloadAdapter() {
+
+ return new IReloadableEditor() {
+
+ @Override
+ public void reloadEditor(Collection<? extends Resource> triggeringResources, ReloadReason reason, DirtyPolicy dirtyPolicy) throws CoreException {
+ // Attempt to re-load, later
+ pendingReload.set(new DeferredReload(triggeringResources, reason, dirtyPolicy));
+
+ // If I am already active, then do it now. Or, if we're not going to ask the user about it, also do it now
+ IWorkbenchPage page = getSite().getPage();
+ if ((page.getActiveEditor() == CoreMultiDiagramEditor.this) || (dirtyPolicy != DirtyPolicy.PROMPT_TO_SAVE)) {
+ pendingReload.get().reload();
+ }
+ }
+
+ @Override
+ public void addEditorReloadListener(IEditorReloadListener listener) {
+ reloadListeners.addIfAbsent(listener);
+ }
+
+ @Override
+ public void removeEditorReloadListener(IEditorReloadListener listener) {
+ reloadListeners.remove(listener);
+ }
+ };
+ }
+
+ private void addSelfReloadListener() {
+ createReloadAdapter().addEditorReloadListener(new IEditorReloadListener() {
+
+ @Override
+ public void editorAboutToReload(EditorReloadEvent event) {
+ event.putContext(new MultiDiagramEditorSelectionContext(event.getEditor()));
+ }
+
+ @Override
+ public void editorReloaded(EditorReloadEvent event) {
+ ((MultiDiagramEditorSelectionContext) event.getContext()).restore(event.getEditor());
+ }
+ });
+ }
+
+ /**
+ * Register an action to be run when I am closed. Any number of such actions may
+ * be added. note that close actions also run on re-load, which behaves to all
+ * outward appearances like a close and re-open.
+ *
+ * @param closeAction
+ * an action to run when I am closed
+ */
+ public void onClose(Runnable closeAction) {
+ closeActions.add(closeAction);
+ }
+
+ @Override
+ protected void deactivate() {
+ getLifecycleManager().fireBeforeClose(this);
+ if (sashModelMngr != null) {
+ sashModelMngr.getSashModelContentChangedProvider().removeListener(contentChangedListener);
+ }
+
+ super.deactivate();
+
+ // dispose available service
+ if (servicesRegistry != null) {
+ try {
+ servicesRegistry.disposeRegistry();
+ servicesRegistry = null;
+ } catch (ServiceMultiException e) {
+ log.error(e);
+ }
+ }
+
+ if (contentChangedListener != null) {
+ this.contentChangedListener = null;
+ }
+
+ if (editorInputChangedListener != null) {
+ this.editorInputChangedListener.dispose();
+ this.editorInputChangedListener = null;
+ }
+
+ for (Runnable next : closeActions) {
+ try {
+ next.run();
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in close action", e); //$NON-NLS-1$
+ }
+ }
+ closeActions.clear();
+
+ transactionalEditingDomain = null;
+ resourceSet = null;
+ undoContext = null;
+ saveAndDirtyService = null;
+ sashModelMngr = null;
+ }
+
+ void initContents() throws PartInitException {
+ loadModelAndServices();
+ loadNestedEditors();
+ }
+
+ @Override
+ public void setFocus() {
+ super.setFocus();
+
+ DeferredReload reload = pendingReload.get();
+ if (reload != null) {
+ reload.reload();
+ }
+ }
+
+ private void doReload() throws CoreException {
+ final IWorkbenchPage page = getSite().getPage();
+ final IWorkbenchPart activePart = page.getActivePart();
+ final IEditorPart activeEditor = page.getActiveEditor();
+
+ final Iterable<? extends IEditorReloadListener> listeners = ImmutableList.copyOf(reloadListeners);
+ final EditorReloadEvent event = new EditorReloadEvent(CoreMultiDiagramEditor.this);
+
+ try {
+ event.dispatchEditorAboutToReload(listeners);
+
+ deactivate();
+
+ initContents();
+
+ activate();
+
+ // My self-listener will be first, to ensure that the pages are all restored before dependents run
+ event.dispatchEditorReloaded(listeners);
+ } finally {
+ event.dispose();
+
+ // Ensure that the editor previously active is active again (if it still exists)
+ if ((activeEditor != null) && page.isPartVisible(activeEditor)) {
+ page.activate(activeEditor);
+ }
+
+ // Ensure that the part previously active is active again (if it still exists and is not the active editor)
+ if ((activePart != null) && (activePart != activeEditor) && page.isPartVisible(activePart)) {
+ page.activate(activePart);
+ }
+ }
+
+ }
+
+ /**
+ * Overrides doSave.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+
+ saveAndDirtyService.doSave(monitor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDirty() {
+ // May happen if the editor has not yet been initialized. In this case, the editor cannot be dirty, so we simply return false.
+ // Bug 410286: The isDirty() method can also be called /after/ the editor has been disposed. Most likely an Eclipse bug?
+ if (saveAndDirtyService == null) {
+ return false;
+ }
+ return saveAndDirtyService.isDirty();
+ }
+
+ /**
+ * Overrides doSaveAs.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ @Override
+ public void doSaveAs() {
+
+ saveAndDirtyService.doSaveAs();
+ }
+
+ /**
+ * Overrides isSaveAsAllowed.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ /**
+ * Overrides getContributorId.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor#getContributorId()
+ */
+ @Override
+ public String getContributorId() {
+ // return Activator.PLUGIN_ID;
+ return "TreeOutlinePage";
+
+ }
+
+ // implements IDiagramWorkbenchPart to restore GMF standard behavior
+ // and delegate to the activeEditor
+
+ /**
+ * Overrides getDiagram.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart#getDiagram()
+ */
+ // public org.eclipse.gmf.runtime.notation.Diagram getDiagram() {
+ // IEditorPart activeEditor = getActiveEditor();
+ // if(activeEditor instanceof DiagramEditor) {
+ // return ((DiagramEditor)activeEditor).getDiagram();
+ // } else {
+ // return null;
+ // }
+ // }
+
+ /**
+ * This method is called from a GMF diagram. It should only be called from GMF diagram code. Normally, the Diagram under the Mouse is a GMF
+ * Diagram. The active Diagram can be another Diagram, not
+ * under the mouse. This is a GMF issue.
+ */
+ // public DiagramEditPart getDiagramEditPart() {
+ //
+ // // Get the editor under the mouse
+ // // IEditorPart activeEditor = rootContainer.getEditorUnderMouse();
+ // IEditorPart activeEditor = getActiveEditor();
+ // if(activeEditor == null) {
+ // return null;
+ // }
+ // // IEditorPart activeEditor = getActiveEditor();
+ // if(activeEditor instanceof DiagramEditor) {
+ // return ((DiagramEditor)activeEditor).getDiagramEditPart();
+ // } else {
+ // // This case should never happen.
+ // // Return null, as the GMF runtime now support it (since 093009)
+ // return null;
+ // }
+ // }
+
+ /**
+ * Overrides getDiagramGraphicalViewer.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart#getDiagramGraphicalViewer()
+ */
+ // public IDiagramGraphicalViewer getDiagramGraphicalViewer() {
+ // IEditorPart activeEditor = getActiveEditor();
+ // if(activeEditor instanceof DiagramEditor) {
+ // return ((DiagramEditor)activeEditor).getDiagramGraphicalViewer();
+ // } else {
+ // return null;
+ // }
+ // }
+
+ /**
+ * Overrides getEditingDomain.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.domain.IEditingDomainProvider#getEditingDomain()
+ */
+ @Override
+ public EditingDomain getEditingDomain() {
+ return transactionalEditingDomain;
+ }
+
+ /**
+ * Throws an UnsupportedOperationException.
+ *
+ * @see org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor#getDiagramEditDomain()
+ */
+ // public DiagramEditDomain getDiagramEditDomain() {
+ // throw new UnsupportedOperationException("Not implemented. Should not be called.");
+ // }
+
+
+ /**
+ * Change the editor input.<BR>
+ * <U>Note</U>: that method should be called within the UI-Thread.
+ *
+ * @see org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor#setEditorInput(org.eclipse.ui.IEditorInput)
+ *
+ * @param newInput
+ * The new input
+ * @deprecated Not used anymore
+ */
+
+ @Override
+ @Deprecated
+ public void setEditorInput(IEditorInput newInput) {
+ setInputWithNotify(newInput);
+ setPartName(newInput.getName());
+ }
+
+ @Override
+ @Deprecated
+ public void gotoMarker(IMarker marker) {
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchPage page = wb.getActiveWorkbenchWindow().getActivePage();
+ boolean first = true;
+ for (IViewReference view : page.getViewReferences()) {
+ // no longer restrict to model explorer (see bug 387578)
+ IWorkbenchPart part = view.getPart(false);
+ if (part instanceof IGotoMarker) {
+ // activate first view implementing the IGotoMarker interface
+ if (first) {
+ page.activate(view.getPart(false));
+ first = false;
+ }
+ ((IGotoMarker) part).gotoMarker(marker);
+ }
+ }
+ }
+
+ private boolean needsRefresh;
+
+ protected void scheduleRefresh() {
+ needsRefresh = true;
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ refreshTabs();
+ }
+ });
+ }
+
+ @Override
+ protected void refreshTabs() {
+ if (!needsRefresh) {
+ return;
+ }
+ needsRefresh = false;
+ super.refreshTabs();
+ }
+
+ @Override
+ public synchronized IEditorPart getActiveEditor() {
+ refreshTabs();
+ return super.getActiveEditor();
+ }
+
+ private final class DeferredReload extends IReloadableEditor.Adapter {
+
+ private final Collection<? extends Resource> triggeringResources;
+
+ private final ReloadReason reason;
+
+ private final DirtyPolicy dirtyPolicy;
+
+ DeferredReload(Collection<? extends Resource> triggeringResources, ReloadReason reason, DirtyPolicy dirtyPolicy) {
+ super(CoreMultiDiagramEditor.this);
+
+ this.triggeringResources = ImmutableSet.copyOf(triggeringResources);
+ this.reason = reason;
+ this.dirtyPolicy = dirtyPolicy;
+ }
+
+ void reload() {
+ try {
+ reloadEditor(triggeringResources, reason, dirtyPolicy);
+ } catch (CoreException e) {
+ // Failed to properly unload/load in place, so just close
+ getSite().getPage().closeEditor(CoreMultiDiagramEditor.this, false);
+
+ StatusManager.getManager().handle(e.getStatus(), StatusManager.LOG | StatusManager.SHOW);
+ }
+ }
+
+ @Override
+ public void reloadEditor(Collection<? extends Resource> triggeringResources, ReloadReason reason, DirtyPolicy dirtyPolicy) throws CoreException {
+ if (!pendingReload.compareAndSet(this, null)) {
+ return;
+ }
+
+ final DirtyPolicy action = dirtyPolicy.resolve(CoreMultiDiagramEditor.this, triggeringResources, reason);
+
+ if ((action == DirtyPolicy.SAVE) && isDirty()) {
+ doSave(new NullProgressMonitor());
+ }
+
+ switch (action) {
+ case SAVE:
+ case DO_NOT_SAVE:
+ if (reason.shouldReload(triggeringResources)) {
+ // Attempt to re-load
+ doReload();
+ } else {
+ // Just close 'er down
+ getSite().getPage().closeEditor(CoreMultiDiagramEditor.this, false);
+ }
+ break;
+ case IGNORE:
+ // Pass
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid resolution of editor re-load dirty policy: " + action); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelManagerServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelManagerServiceFactory.java
new file mode 100644
index 00000000000..1f13fedb84b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelManagerServiceFactory.java
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * Copyright (c) 2013 Cedric Dumoulin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager;
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageModelFactoryRegistry;
+import org.eclipse.papyrus.infra.ui.extension.diagrameditor.PluggableEditorFactoryReader;
+
+/**
+ * Service Factory to create the {@link DiSashModelManager} service.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class DiSashModelManagerServiceFactory implements IServiceFactory {
+
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ private SashModel sashModel;
+
+ private DiSashModelManager sashModelMngr;
+
+ private ServicesRegistry servicesRegistry;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+
+ this.servicesRegistry = servicesRegistry;
+ // Get required service
+ transactionalEditingDomain = servicesRegistry.getService(TransactionalEditingDomain.class);
+
+ // Get the model holding the contentProvider
+ sashModel = SashModelUtils.getSashModelChecked(servicesRegistry);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+
+ // Read declared editors
+ PageModelFactoryRegistry pageModelRegistry = new PageModelFactoryRegistry();
+ PluggableEditorFactoryReader editorReader = new PluggableEditorFactoryReader(Activator.PLUGIN_ID);
+ editorReader.populate(pageModelRegistry, servicesRegistry);
+
+ if (sashModel.getResource() == null) {
+ throw new ServiceException("Can't start " + this.getClass().getSimpleName() + "'. Required model (SashModel) should be loaded prior starting the service."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ // create the service
+ sashModelMngr = new DiSashModelManager(pageModelRegistry, sashModel.getResource(), transactionalEditingDomain);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
+ *
+ * @return
+ * @throws ServiceException
+ */
+ @Override
+ public Object createServiceInstance() throws ServiceException {
+
+ // Start locally the service if needed.
+ // Question: Can createServiceInstance() method be called before
+ // startService() is called ?
+ if (sashModelMngr == null) {
+ startService();
+ }
+
+ return sashModelMngr;
+ }
+
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelMngrServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelMngrServiceFactory.java
new file mode 100644
index 00000000000..ad0806cff77
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/DiSashModelMngrServiceFactory.java
@@ -0,0 +1,101 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelMngr;
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageModelFactoryRegistry;
+import org.eclipse.papyrus.infra.ui.extension.diagrameditor.PluggableEditorFactoryReader;
+
+/**
+ * Service Factory to create the {@link DiSashModelMngr} service.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class DiSashModelMngrServiceFactory implements IServiceFactory {
+
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ private SashModel sashModel;
+
+ private DiSashModelMngr sashModelMngr;
+
+ private ServicesRegistry servicesRegistry;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+
+ this.servicesRegistry = servicesRegistry;
+ // Get required service
+ transactionalEditingDomain = servicesRegistry.getService(TransactionalEditingDomain.class);
+
+ // Get the model holding the contentProvider
+ sashModel = SashModelUtils.getSashModelChecked(servicesRegistry);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+
+ // Read declared editors
+ PageModelFactoryRegistry pageModelRegistry = new PageModelFactoryRegistry();
+ PluggableEditorFactoryReader editorReader = new PluggableEditorFactoryReader(Activator.PLUGIN_ID);
+ editorReader.populate(pageModelRegistry, servicesRegistry);
+
+ if (sashModel.getResource() == null) {
+ throw new ServiceException("Can't start " + this.getClass().getSimpleName() + "'. Required model (SashModel) should be loaded prior starting the service."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ // create the service
+ sashModelMngr = new DiSashModelMngr(pageModelRegistry, sashModel.getResource());
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
+ *
+ * @return
+ * @throws ServiceException
+ */
+ @Override
+ public Object createServiceInstance() throws ServiceException {
+
+ // Start locally the service if needed.
+ // Question: Can createServiceInstance() method be called before
+ // startService() is called ?
+ if (sashModelMngr == null) {
+ startService();
+ }
+
+ return sashModelMngr;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IMultiDiagramEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IMultiDiagramEditor.java
new file mode 100644
index 00000000000..4193c25cf3e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IMultiDiagramEditor.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+
+/**
+ * Interface implemented by the main multipage editor. This interface list the
+ * methods available to diagram editors. Diagram editors can relies on this
+ * interface to retrieve services from the main multi diagram editor. <br>
+ * This interface should stay minimalist, as the editor is not designed to
+ * handle the services itself. A service should be retrieved by using {@link #getServicesRegistry()}.
+ *
+ *
+ * @author cedric dumoulin
+ *
+ * TODO remove extends IEditingDomainProvider. This interface should be
+ * independant of any technology (EMF, GMF, ...). If the EditingDomain
+ * is required, it can be retrieved by the registry.
+ *
+ */
+public interface IMultiDiagramEditor extends IEditorPart {
+
+ /**
+ * Returns the service registry associated to the editor.
+ *
+ * @return the servicesRegistry The registry.
+ */
+ public ServicesRegistry getServicesRegistry();
+
+ /**
+ * Return the editor site.
+ *
+ * @return
+ */
+ @Override
+ public IEditorSite getEditorSite();
+
+ /**
+ * Get the editor input.
+ *
+ * @return
+ */
+ @Override
+ public IEditorInput getEditorInput();
+
+ /**
+ * Change the editor input.
+ *
+ * @param newInput
+ * The new input.
+ * @deprecated No replacement. Input can't be changed on multi editors.
+ */
+ @Deprecated
+ public void setEditorInput(IEditorInput newInput);
+
+ /**
+ * Returns the edit domain shared among editors
+ *
+ * @return the edit domain shared among editors
+ * @deprecated Use {@link #getServicesRegistry()} or {@link #getAdapter(Class)}
+ */
+ // FIXME Remove it (GMF dependency)
+ // public DiagramEditDomain getDiagramEditDomain();
+
+ /**
+ * Get the currently active nested Editor.
+ */
+ public IEditorPart getActiveEditor();
+
+ /**
+ * Get the property sheet page associated to the Editor.
+ *
+ * @return the property sheet page associated to the Editor.
+ * @deprecated Use {@link #getServicesRegistry()} or {@link #getAdapter(Class)}
+ */
+ // @Deprecated
+ // public IPropertySheetPage getPropertySheetPage();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IPapyrusPageInput.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IPapyrusPageInput.java
new file mode 100644
index 00000000000..50594efbec8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IPapyrusPageInput.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * An IEditorInput used to reference the page(s) to open
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IPapyrusPageInput extends IEditorInput {
+
+ /**
+ * @return the list of pages to open
+ */
+ public URI[] getPages();
+
+ /**
+ *
+ * @return true if the editor should close all other pages
+ */
+ public boolean closeOtherPages();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IReloadableEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IReloadableEditor.java
new file mode 100644
index 00000000000..92bff539cf7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/IReloadableEditor.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2014, 2016 CEA, 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 (CEA) - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editor;
+
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.ui.URIEditorInput;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.tools.util.CoreExecutors;
+import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.reload.IEditorReloadListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
+
+
+/**
+ * An {@linkplain IAdaptable adapter protocol} for editors that know how to internally
+ * reload themselves without disturbing the workbench window's perspective layout.
+ */
+public interface IReloadableEditor {
+
+ /**
+ * Reloads me in-place in the perspective layout.
+ *
+ * @param triggeringResources
+ * the resources that have changed in some way, triggering re-load
+ * @param reason
+ * the reason why the re-load is being requested
+ * @param dirtyPolicy
+ * how the client would like to handle the case of a dirty editor
+ *
+ * @throws CoreException
+ * on any failure to unload, reload, or whatever
+ */
+ void reloadEditor(Collection<? extends Resource> triggeringResources, ReloadReason reason, DirtyPolicy dirtyPolicy) throws CoreException;
+
+ void addEditorReloadListener(IEditorReloadListener listener);
+
+ void removeEditorReloadListener(IEditorReloadListener listener);
+
+ /**
+ * An enumeration of the reason why some resources that an editor has loaded are triggering a re-load (or close).
+ */
+ enum ReloadReason {
+ /** Resources have changed in persistent storage. */
+ RESOURCES_CHANGED,
+ /** Resources have been deleted from persistent storage. */
+ RESOURCES_DELETED;
+
+ /**
+ * Queries whether, under ordinary circumstances, the editor should attempt to re-load to pick up changes in its dependent resources.
+ *
+ * @param triggeringResources
+ * the resources triggering re-load (or close)
+ *
+ * @return whether the editor should re-load
+ */
+ public boolean shouldReload(Collection<? extends Resource> triggeringResources) {
+ return this != RESOURCES_DELETED;
+ }
+ }
+
+ /**
+ * An enumeration of policies that clients may request to govern what to do with the editor before re-load (or close) if it should happen to be
+ * dirty. Note that editors are free to honour the requested policy or not, according to their needs.
+ */
+ enum DirtyPolicy {
+ /**
+ * Save the editor without prompting.
+ */
+ SAVE,
+ /**
+ * Do not save the editor; just discard pending changes and re-load (or close).
+ */
+ DO_NOT_SAVE,
+ /**
+ * Do not re-load (or close) the editor; just keep pending changes and deal with conflicts later.
+ */
+ IGNORE,
+ /**
+ * Prompt the user to inquire whether to save, discard pending changes, or not re-load (or close) at all.
+ * Note that the user prompt must always result in one of the other policies being actually applied.
+ */
+ PROMPT_TO_SAVE {
+
+ @Override
+ public DirtyPolicy resolve(IEditorPart editor, final Collection<? extends Resource> triggeringResources, final ReloadReason reason) throws CoreException {
+ final boolean dirty = editor.isDirty();
+
+ if (!dirty) {
+ if (reason.shouldReload(triggeringResources)) {
+ // Just re-load it. Simple
+ return DO_NOT_SAVE;
+ } else if (isPrincipalResourceAffected(editor, triggeringResources)) {
+ // Just close it. Also simple
+ return DO_NOT_SAVE;
+ }
+ }
+
+ final String editorName = getEditorName(editor);
+
+ final boolean allReadOnly = allReadOnly(triggeringResources);
+ final String promptTitle;
+ final String promptIntro;
+ final String saveOption;
+ final String dontSaveOption;
+ final String ignoreOption = "Ignore";
+
+ switch (reason) {
+ case RESOURCES_DELETED:
+ promptTitle = "Resources Deleted";
+ promptIntro = NLS.bind("Some resources used by \"{0}\" have been deleted.", editorName);
+ saveOption = "Save and Close";
+ dontSaveOption = "Close Editor";
+ break;
+ default:
+ promptTitle = "Resources Changed";
+ promptIntro = NLS.bind("Some resources used by \"{0}\" have changed.", editorName);
+ saveOption = "Save and Re-open";
+ dontSaveOption = "Re-open Editor";
+ break;
+ }
+
+ Callable<DirtyPolicy> result;
+
+ if (allReadOnly) {
+ // Only read-only models have changed. We (most likely) won't save them within this current editor. As they are already loaded, we can just continue.
+ result = new Callable<DirtyPolicy>() {
+
+ @Override
+ public DirtyPolicy call() {
+ Shell parentShell = Display.getCurrent().getActiveShell();
+
+ final String message;
+ final String[] options;
+ if (dirty) {
+ message = promptIntro + " Note: all these resources are loaded in read-only mode and won't be overridden if you choose to save. Unsaved changes will be lost.";
+ options = new String[] { saveOption, dontSaveOption, ignoreOption };
+ } else {
+ message = promptIntro;
+ options = new String[] { dontSaveOption, ignoreOption };
+ }
+
+ final MessageDialog dialog = new MessageDialog(parentShell, promptTitle, null, message, MessageDialog.WARNING, options, 0) {
+
+ @Override
+ protected void setShellStyle(int newShellStyle) {
+ super.setShellStyle(newShellStyle | SWT.SHEET);
+ }
+ };
+ final int answer = dialog.open();
+
+ DirtyPolicy result;
+
+ if (answer == SWT.DEFAULT) {
+ // User hit Esc or dismissed the dialog with the window manager button. Ignore
+ result = IGNORE;
+ } else if (dirty) {
+ result = values()[answer];
+ } else {
+ result = values()[answer + 1]; // Account for the missing "Save and Xxx" option
+ }
+
+ return result;
+ }
+ };
+ } else {
+ // At least one read-write resource has changed. Potential conflicts.
+ result = new Callable<DirtyPolicy>() {
+
+ @Override
+ public DirtyPolicy call() {
+ DirtyPolicy result = IGNORE;
+
+ final Shell parentShell = Display.getCurrent().getActiveShell();
+ final String action = reason.shouldReload(triggeringResources) ? "re-open" : "close";
+ final String message;
+
+ if (dirty) {
+ message = promptIntro + NLS.bind(" Do you wish to {0} the current editor? Unsaved changes will be lost.", action);
+ } else {
+ message = promptIntro + NLS.bind(" Do you wish to {0} the current editor?", action);
+ }
+
+ final String[] options = { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL };
+ final MessageDialog dialog = new MessageDialog(parentShell, promptTitle, null, message, MessageDialog.WARNING, options, 0) {
+
+ @Override
+ protected void setShellStyle(int newShellStyle) {
+ super.setShellStyle(newShellStyle | SWT.SHEET);
+ }
+ };
+ if (dialog.open() == 0) {
+ result = DO_NOT_SAVE;
+ }
+
+ return result;
+ }
+ };
+ }
+
+ try {
+ return CoreExecutors.getUIExecutorService().syncCall(result);
+ } catch (ExecutionException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to determine dirty policy for editor re-load.", e));
+ } catch (InterruptedException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Interrupted in determining dirty policy for editor re-load.", e));
+ }
+ }
+ };
+
+ /**
+ * Queries the default dirty policy currently in effect. The default-default is {@link #PROMPT_TO_SAVE}.
+ *
+ * @return the default policy
+ */
+ public static DirtyPolicy getDefault() {
+ return PROMPT_TO_SAVE;
+ }
+
+ /**
+ * Resolves me to a specific actionable policy, based on the resources that are triggering re-load (or close) and the reason.
+ *
+ * @param editor
+ * the editor to be re-loaded
+ * @param triggeringResources
+ * the resources (possibly an empty collection) that have changed
+ * @param reloadReason
+ * the reason why re-load (or close) is triggered
+ *
+ * @return the specific policy to implement in re-loading the editor
+ *
+ * @throws CoreException
+ * on failure to resolve the specific policy
+ */
+ public DirtyPolicy resolve(IEditorPart editor, Collection<? extends Resource> triggeringResources, ReloadReason reason) throws CoreException {
+ return this;
+ }
+
+ String getEditorName(IEditorPart editor) {
+ ModelSet modelSet = getModelSet(editor);
+ return (modelSet == null) ? editor.getTitle() : modelSet.getURIWithoutExtension().lastSegment();
+ }
+
+ private ModelSet getModelSet(IEditorPart editor) {
+ ModelSet result = null;
+
+ if (editor instanceof IMultiDiagramEditor) {
+ try {
+ result = ((IMultiDiagramEditor) editor).getServicesRegistry().getService(ModelSet.class);
+ } catch (ServiceException e) {
+ // No problem. We have a fall-back
+ Activator.log.error(e);
+ }
+ }
+
+ return result;
+ }
+
+ boolean isPrincipalResourceAffected(IEditorPart editor, Collection<? extends Resource> triggeringResources) {
+ boolean result = false;
+
+ ModelSet modelSet = getModelSet(editor);
+ if (modelSet != null) {
+ URI principalURI = modelSet.getURIWithoutExtension();
+ for (Resource next : triggeringResources) {
+ if (next.getURI().trimFileExtension().equals(principalURI)) {
+ result = true;
+ break;
+ }
+ }
+ } else {
+ URI principalURI = getURI(editor.getEditorInput());
+ if (principalURI != null) {
+ for (Resource next : triggeringResources) {
+ if (next.getURI().equals(principalURI)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private URI getURI(IEditorInput input) {
+ URI result = null;
+
+ if (input instanceof URIEditorInput) {
+ result = ((URIEditorInput) input).getURI();
+ } else if (input instanceof IURIEditorInput) {
+ result = URI.createURI(((IURIEditorInput) input).getURI().toString());
+ }
+
+ return result;
+ }
+
+ protected boolean allReadOnly(Collection<? extends Resource> resources) {
+ for (Resource resource : resources) {
+ EditingDomain domain = TransactionUtil.getEditingDomain(resource);
+ if ((domain == null) || !domain.isReadOnly(resource)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * A convenience adapter for editors that don't actually know how to reload themselves in place.
+ * It simply closes the editor and then opens it again on the original input.
+ */
+ class Adapter implements IReloadableEditor {
+
+ private final IEditorPart editor;
+
+ public Adapter(IEditorPart editor) {
+ super();
+
+ this.editor = editor;
+ }
+
+ public static IReloadableEditor getAdapter(IMultiDiagramEditor editor) {
+ return PlatformHelper.getAdapter(editor, IReloadableEditor.class, () -> new Adapter(editor));
+ }
+
+ @Override
+ public void reloadEditor(Collection<? extends Resource> triggeringResources, ReloadReason reason, DirtyPolicy dirtyPolicy) throws CoreException {
+ final IWorkbenchPage page = editor.getSite().getPage();
+ final IEditorInput currentInput = editor.getEditorInput();
+
+ final Display display = editor.getSite().getShell().getDisplay();
+
+ final String editorId = editor.getSite().getId();
+
+ final DirtyPolicy action = dirtyPolicy.resolve(editor, triggeringResources, reason);
+ final boolean save = action == DirtyPolicy.SAVE;
+
+ if (save && editor.isDirty()) {
+ editor.doSave(new NullProgressMonitor());
+ }
+
+ if (action != DirtyPolicy.IGNORE) {
+ page.closeEditor(editor, save);
+
+ // If resources were deleted, we close and don't re-open
+ if (reason.shouldReload(triggeringResources)) {
+ display.asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ IDE.openEditor(page, currentInput, editorId);
+ } catch (PartInitException ex) {
+ Activator.log.error(ex);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public void addEditorReloadListener(IEditorReloadListener listener) {
+ // Don't need to track these listeners because I never properly reload an editor
+ }
+
+ @Override
+ public void removeEditorReloadListener(IEditorReloadListener listener) {
+ // Don't need to track these listeners because I never properly reload an editor
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramEditorSelectionContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramEditorSelectionContext.java
new file mode 100644
index 00000000000..fc0302004dd
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramEditorSelectionContext.java
@@ -0,0 +1,291 @@
+/*
+ * 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.ui.editor;
+
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IComponentPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IEditorPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IPageVisitor;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.reload.CompositeReloadContext;
+import org.eclipse.papyrus.infra.ui.editor.reload.DelegatingReloadContext;
+import org.eclipse.papyrus.infra.ui.editor.reload.EMFSelectionContext;
+import org.eclipse.papyrus.infra.ui.editor.reload.EditorReloadEvent;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+
+/**
+ * A {@linkplain EditorReloadEvent reload event} context that restores the selection of which editor page
+ * is active in an {@link IMultiDiagramEditor} that is reloaded and delegates to its pages to capture
+ * re-load context for each to restore whatever they need to restore (internal selections etc.).
+ */
+class MultiDiagramEditorSelectionContext extends CompositeReloadContext {
+
+ private ISashWindowsContainer sashContainer;
+
+ private final List<URI> resourcesToLoad;
+
+ MultiDiagramEditorSelectionContext(IMultiDiagramEditor editor) {
+ super();
+
+ init(editor);
+
+ resourcesToLoad = computeResourcesToLoad(editor);
+
+ IPage active = sashContainer.getActiveSashWindowsPage();
+ DiagramPageContext activePage = null;
+
+ Set<IPage> visiblePages = Sets.newIdentityHashSet();
+ visiblePages.addAll(sashContainer.getVisiblePages());
+
+ List<IPage> allPages = getAllPages(sashContainer);
+
+ for (IPage page : allPages) {
+ final DelegatingReloadContext delegator = (page instanceof IEditorPage) ? add(new DelegatingReloadContext(((IEditorPage) page).getIEditorPart())) : null;
+ DiagramPageContext context;
+
+ if (page == active) {
+ // This one will have the selection of the active page
+ context = new DiagramPageContext(new VisiblePageSelectionProvider(page), page, delegator);
+ activePage = context;
+ } else {
+ if (visiblePages.contains(page)) {
+ // This one must be selected in its folder in order to make it visible again
+ context = new DiagramPageContext(new VisiblePageSelectionProvider(page), page, delegator);
+ } else {
+ context = new DiagramPageContext(EmptySelectionProvider.INSTANCE, page, delegator);
+ }
+
+ // We make sure always to restore the active page last
+ // so that it will not only be visible but also the
+ // over-all active page
+ add(context);
+ }
+ }
+
+ if (activePage != null) {
+ // Restore this one last
+ add(activePage);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ sashContainer = null;
+ super.dispose();
+ }
+
+ private List<IPage> getAllPages(ISashWindowsContainer container) {
+ final List<IPage> result = Lists.newArrayList();
+
+ container.visit(new IPageVisitor() {
+
+ @Override
+ public void accept(IEditorPage page) {
+ result.add(page);
+ }
+
+ @Override
+ public void accept(IComponentPage page) {
+ result.add(page);
+ }
+ });
+
+ return result;
+ }
+
+ private void init(IMultiDiagramEditor editor) {
+ sashContainer = AdapterUtils.adapt(editor, ISashWindowsContainer.class, null);
+ }
+
+ void restore(IMultiDiagramEditor editor) {
+ init(editor);
+
+ // Forcibly re-load all previously loaded resources to that
+ // (a) we don't lose imports that weren't yet used, and
+ // (b) we can restore selections in resources that wouldn't be loaded until proxies resolve later
+ reloadResources(editor);
+
+ ISelectionProvider selectionProvider = new VisiblePageSelectionProvider();
+ for (DiagramPageContext next : getReloadContexts(DiagramPageContext.class)) {
+ next.restore(selectionProvider);
+ }
+ }
+
+ protected List<URI> computeResourcesToLoad(IMultiDiagramEditor editor) {
+ List<URI> result = null;
+
+ ResourceSet rset = getResourceSet(editor);
+ if (rset != null) {
+ result = Lists.newArrayListWithCapacity(rset.getResources().size());
+
+ for (Resource next : rset.getResources()) {
+ if (next.isLoaded()) {
+ result.add(next.getURI());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected void reloadResources(IMultiDiagramEditor editor) {
+ if (resourcesToLoad != null) {
+ ResourceSet rset = getResourceSet(editor);
+ if (rset != null) {
+ for (URI next : resourcesToLoad) {
+ try {
+ rset.getResource(next, true);
+ } catch (Exception e) {
+ Activator.log.error("Failed to restore loaded resource: " + next, e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+
+ protected final ResourceSet getResourceSet(IMultiDiagramEditor editor) {
+ ResourceSet result = null;
+
+ EditingDomain editingDomain = editor.getAdapter(EditingDomain.class);
+ if (editingDomain != null) {
+ result = editingDomain.getResourceSet();
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ private class DiagramPageContext extends EMFSelectionContext {
+
+ private URI pageRef;
+
+ private DelegatingReloadContext pageContext;
+
+ DiagramPageContext(ISelectionProvider structuredSelectionProvider, IPage page, DelegatingReloadContext pageContext) {
+ super(structuredSelectionProvider);
+
+ this.pageContext = pageContext;
+ this.pageRef = getToken(page.getRawModel());
+ }
+
+ @Override
+ public void restore(ISelectionProvider structuredSelectionProvider) {
+ IPage page = sashContainer.lookupModelPage(resolveToken(pageRef));
+
+ if ((pageContext != null) && (page instanceof IEditorPage)) {
+ pageContext.restore(((IEditorPage) page).getIEditorPart());
+ }
+
+ super.restore(structuredSelectionProvider);
+ }
+
+ @Override
+ protected Object deresolveSelectableElement(Object selectableElement) {
+ return (selectableElement instanceof IPage) ? ((IPage) selectableElement).getRawModel() : super.deresolveSelectableElement(selectableElement);
+ }
+
+ @Override
+ protected Object resolveSelectableElement(Object deresolved) {
+ return sashContainer.lookupModelPage(deresolved);
+ }
+ }
+
+ private static class EmptySelectionProvider implements ISelectionProvider {
+
+ static final EmptySelectionProvider INSTANCE = new EmptySelectionProvider();
+
+ EmptySelectionProvider() {
+ super();
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return StructuredSelection.EMPTY;
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ // Pass
+ }
+
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ // Not needed because the selection is always empty
+ }
+
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ // Not needed because the selection is always empty
+ }
+
+ }
+
+ private class VisiblePageSelectionProvider implements ISelectionProvider {
+
+ private final IStructuredSelection selection;
+
+ VisiblePageSelectionProvider() {
+ this(null);
+ }
+
+ VisiblePageSelectionProvider(IPage visible) {
+ super();
+
+ this.selection = (visible == null) ? StructuredSelection.EMPTY : new StructuredSelection(visible);
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return selection;
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ if (!selection.isEmpty()) {
+ IPage page = (IPage) ((IStructuredSelection) selection).getFirstElement();
+ sashContainer.selectPage(page);
+ }
+ }
+
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ // Not needed
+ }
+
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ // Not needed
+ }
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramPropertySheetPage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramPropertySheetPage.java
new file mode 100644
index 00000000000..9ef43cb4cd3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/MultiDiagramPropertySheetPage.java
@@ -0,0 +1,178 @@
+/*****************************************************************************
+ * Copyright (c) 2014, 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:
+ * CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 469188
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.ui.URIEditorInput;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.infra.core.operation.DelegatingUndoContext;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
+import org.eclipse.papyrus.infra.ui.editor.reload.EditorReloadEvent;
+import org.eclipse.papyrus.infra.ui.editor.reload.IEditorReloadListener;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.operations.RedoActionHandler;
+import org.eclipse.ui.operations.UndoActionHandler;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.views.properties.PropertyShowInContext;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+
+/**
+ * A specialized property-sheet page that knows how to restore the Property Sheet view's input from the workbench part
+ * that most recently gave it its input, after a {@link CoreMultiDiagramEditor} has been re-loaded.
+ */
+class MultiDiagramPropertySheetPage extends TabbedPropertySheetPage implements IEditorReloadListener {
+
+ private final CoreMultiDiagramEditor multiDiagramEditor;
+
+ private UndoActionHandler undo;
+ private RedoActionHandler redo;
+ private DelegatingUndoContext undoContext;
+
+ public MultiDiagramPropertySheetPage(CoreMultiDiagramEditor editor) {
+ super(editor);
+
+ this.multiDiagramEditor = editor;
+ IReloadableEditor.Adapter.getAdapter(editor).addEditorReloadListener(this);
+ }
+
+ @Override
+ public void dispose() {
+ IReloadableEditor.Adapter.getAdapter(multiDiagramEditor).removeEditorReloadListener(this);
+
+ if (undo != null) {
+ undo.dispose();
+ }
+ if (redo != null) {
+ redo.dispose();
+ }
+
+ super.dispose();
+ }
+
+ @Override
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (selection.isEmpty() && (part instanceof IMultiDiagramEditor)) {
+ // Perhaps the user selected a page such as the Welcome Page that
+ // isn't an editor and so doesn't have a selection
+ IMultiDiagramEditor editor = (IMultiDiagramEditor) part;
+ ISashWindowsContainer sash = editor.getAdapter(ISashWindowsContainer.class);
+ if (sash != null) {
+ if ((sash.getActiveEditor() == null) && (sash.getActiveSashWindowsPage() != null)) {
+ // Yep, that's the case, here. So show the properties of the input
+ // resource (usually a DI file)
+ IEditorInput input = editor.getEditorInput();
+ Object newSelection;
+ if (input instanceof IFileEditorInput) {
+ newSelection = ((IFileEditorInput) input).getFile();
+ } else if (input instanceof IStorageEditorInput) {
+ IStorageEditorInput storageInput = (IStorageEditorInput) input;
+ try {
+ newSelection = storageInput.getStorage();
+ } catch (CoreException e) {
+ newSelection = storageInput;
+ }
+ } else if (input instanceof IURIEditorInput) {
+ newSelection = ((IURIEditorInput) input).getURI();
+ } else if (input instanceof URIEditorInput) {
+ newSelection = ((URIEditorInput) input).getURI();
+ } else {
+ newSelection = null;
+ }
+
+ if (newSelection != null) {
+ selection = new StructuredSelection(newSelection);
+ }
+ }
+ }
+ }
+
+ super.selectionChanged(part, selection);
+ }
+
+ @Override
+ public void editorAboutToReload(EditorReloadEvent event) {
+ Object propertySheet = getSite().getService(IViewPart.class);
+ if (propertySheet instanceof IShowInSource) {
+ ShowInContext context = ((IShowInSource) propertySheet).getShowInContext();
+
+ if (context instanceof PropertyShowInContext) {
+ IWorkbenchPart inputPart = ((PropertyShowInContext) context).getPart();
+ if (inputPart != null) {
+ event.putContext(inputPart);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void editorReloaded(EditorReloadEvent event) {
+ final IWorkbenchPart inputPart = (IWorkbenchPart) event.getContext();
+ if (inputPart != null) {
+ final Object propertySheet = getSite().getService(IViewPart.class);
+ if (propertySheet instanceof IPartListener) {
+ // Kick it with this part
+ ((IPartListener) propertySheet).partActivated(inputPart);
+
+ // And again later to get its new selection (we don't know when its selection may be restored relative to us)
+ getSite().getShell().getDisplay().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ ISelectionProvider selectionProvider = inputPart.getSite().getSelectionProvider();
+ if (selectionProvider != null) {
+ ((ISelectionListener) propertySheet).selectionChanged(inputPart, selectionProvider.getSelection());
+ }
+ }
+ });
+ }
+ }
+
+ // The editor will have a new undo context (because it will have a new editing domain)
+ if (undoContext != null) {
+ undoContext.setDelegate(PlatformHelper.getAdapter(multiDiagramEditor, IUndoContext.class));
+ }
+ }
+
+ @Override
+ public void setActionBars(IActionBars actionBars) {
+ super.setActionBars(actionBars);
+
+ undoContext = new DelegatingUndoContext();
+ undoContext.setDelegate(PlatformHelper.getAdapter(multiDiagramEditor, IUndoContext.class));
+
+ undo = new UndoActionHandler(multiDiagramEditor.getSite(), undoContext);
+ redo = new RedoActionHandler(multiDiagramEditor.getSite(), undoContext);
+
+ actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undo);
+ actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redo);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageIconRegistryServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageIconRegistryServiceFactory.java
new file mode 100644
index 00000000000..c35a776b83a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageIconRegistryServiceFactory.java
@@ -0,0 +1,71 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IPageIconsRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageIconsRegistry;
+import org.eclipse.papyrus.infra.ui.extension.diagrameditor.PluggableEditorFactoryReader;
+
+/**
+ * Service Factory to register {@link IPageIconsRegistry}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class PageIconRegistryServiceFactory implements IServiceFactory {
+
+ private PageIconsRegistry pageIconsRegistry;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ if (pageIconsRegistry != null) {
+ pageIconsRegistry.dispose();
+ }
+ }
+
+ /**
+ * Create and populate a {@link PageIconsRegistry}. Return it as the service
+ * instance.
+ *
+ * @return
+ */
+ @Override
+ public Object createServiceInstance() {
+ if (pageIconsRegistry == null) {
+ pageIconsRegistry = new PageIconsRegistry();
+ PluggableEditorFactoryReader editorReader = new PluggableEditorFactoryReader(Activator.PLUGIN_ID);
+ editorReader.populate(pageIconsRegistry);
+ }
+ return pageIconsRegistry;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageMngrServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageMngrServiceFactory.java
new file mode 100644
index 00000000000..b7657e6ce1a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PageMngrServiceFactory.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2011, 2016 LIFL, 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:
+ * LIFL - Initial API and implementation
+ * Christian W. Damus - bugs 415638, 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager;
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+
+/**
+ * A service factory to create the {@link IPageMngr} service. This
+ * serviceFactory depends on {@link ISashWindowsContentProvider} service.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class PageMngrServiceFactory implements IServiceFactory {
+
+ /**
+ * The sashModelMangr.
+ */
+ private DiSashModelManager sashModelMngr;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+
+ // Get required services
+ sashModelMngr = servicesRegistry.getService(DiSashModelManager.class);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
+ *
+ * @return
+ * @throws ServiceException
+ * if the required sash model manager service is unavailable
+ */
+ @Override
+ public Object createServiceInstance() throws ServiceException {
+ if (sashModelMngr == null) {
+ throw new ServiceNotFoundException(DiSashModelManager.class.getName());
+ }
+ return sashModelMngr.getIPageManager();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PapyrusPageInput.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PapyrusPageInput.java
new file mode 100644
index 00000000000..84d317fc793
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/PapyrusPageInput.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Basic implementation of {@link IPapyrusPageInput}
+ *
+ * @author Camille Letavernier
+ */
+public class PapyrusPageInput extends FileEditorInput implements IPapyrusPageInput {
+
+ private final URI[] pages;
+
+ private final boolean closeOtherPages;
+
+ /**
+ * Creates a new PapyrusPageInput
+ *
+ * @param diFile
+ * The file resource
+ * @param pages
+ * The pageIdentifiers of the pages to open
+ * @param closeOtherPages
+ * True if only the selected pages should be opened. All other pages will be closed.
+ */
+ public PapyrusPageInput(IFile diFile, URI[] pages, boolean closeOtherPages) {
+ super(diFile);
+ this.pages = pages;
+ this.closeOtherPages = closeOtherPages;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URI[] getPages() {
+ return pages;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean closeOtherPages() {
+ return closeOtherPages;
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/CompositeReloadContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/CompositeReloadContext.java
new file mode 100644
index 00000000000..3eabad5cbf3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/CompositeReloadContext.java
@@ -0,0 +1,86 @@
+/*
+ * 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.ui.editor.reload;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+
+/**
+ * An {@linkplain EditorReloadEvent#putContext(Object) editor reload context} that composes other reload contexts.
+ * This should be used whenever a {@linkplain IReloadContextProvider reload context provider} supplies multiple
+ * reload contexts, to ensure that they are properly initialized by the reload system.
+ */
+public class CompositeReloadContext implements IDisposableReloadContext, IAdaptable {
+
+ private final Collection<Object> reloadContexts;
+
+ public CompositeReloadContext() {
+ this(Collections.EMPTY_LIST);
+ }
+
+ public CompositeReloadContext(Iterable<?> reloadContexts) {
+ super();
+
+ this.reloadContexts = Lists.newArrayList(reloadContexts);
+ }
+
+ public <T> T add(T reloadContext) {
+ reloadContexts.add(reloadContext);
+ return reloadContext;
+ }
+
+ public Iterable<?> getReloadContexts() {
+ return Collections.unmodifiableCollection(reloadContexts);
+ }
+
+ public <T> Iterable<T> getReloadContexts(Class<T> type) {
+ return Iterables.filter(getReloadContexts(), type);
+ }
+
+ @Override
+ public void dispose() {
+ for (Object next : reloadContexts) {
+ if (next instanceof IDisposableReloadContext) {
+ ((IDisposableReloadContext) next).dispose();
+ }
+ }
+
+ reloadContexts.clear();
+ }
+
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return (adapter == IInternalEMFSelectionContext.class) ? getEMFContext() : null;
+ }
+
+ private IInternalEMFSelectionContext getEMFContext() {
+ IInternalEMFSelectionContext result = null;
+
+ for (Object next : reloadContexts) {
+ if (AdapterUtils.adapt(next, IInternalEMFSelectionContext.class, null) != null) {
+ // We need the adapter
+ result = new IInternalEMFSelectionContext.Composite(this);
+ break;
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/DelegatingReloadContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/DelegatingReloadContext.java
new file mode 100644
index 00000000000..718b376c2ba
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/DelegatingReloadContext.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ui.editor.reload;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+
+
+/**
+ * An {@linkplain EditorReloadEvent#putContext(Object) editor reload context} that delegates to another reload context.
+ * This should be used whenever a {@linkplain IReloadContextProvider reload context provider} is needed to get a reload
+ * context to delegate to.
+ */
+public class DelegatingReloadContext implements IDisposableReloadContext, IAdaptable {
+
+ private Object delegate;
+
+ public DelegatingReloadContext(Object reloadContextProvider) {
+ super();
+
+ IReloadContextProvider provider = AdapterUtils.adapt(reloadContextProvider, IReloadContextProvider.class, null);
+ if (provider != null) {
+ delegate = provider.createReloadContext();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (delegate instanceof IDisposableReloadContext) {
+ ((IDisposableReloadContext) delegate).dispose();
+ }
+
+ delegate = null;
+ }
+
+ public Object getDelegate() {
+ return delegate;
+ }
+
+ public void restore(Object reloadContextProvider) {
+ if (delegate != null) {
+ IReloadContextProvider provider = AdapterUtils.adapt(reloadContextProvider, IReloadContextProvider.class, null);
+ if (provider != null) {
+ provider.restore(delegate);
+ }
+ }
+ }
+
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return (adapter == IInternalEMFSelectionContext.class) ? getEMFContext() : null;
+ }
+
+ private IInternalEMFSelectionContext getEMFContext() {
+ IInternalEMFSelectionContext result = null;
+
+ if ((delegate != null) && (AdapterUtils.adapt(delegate, IInternalEMFSelectionContext.class, null) != null)) {
+ // We need the adapter
+ result = new IInternalEMFSelectionContext.Delegating(this);
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFSelectionContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFSelectionContext.java
new file mode 100644
index 00000000000..e8eea1033cc
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFSelectionContext.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ui.editor.reload;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.viewers.ISelectionProvider;
+
+
+/**
+ * A convenient selection re-load context for UIs that present EMF-based content.
+ */
+public class EMFSelectionContext extends SelectionContext<ISelectionProvider, URI> implements IAdaptable {
+
+ private IInternalEMFSelectionContext emfContext;
+
+ public EMFSelectionContext(ISelectionProvider structuredSelectionProvider) {
+ super(structuredSelectionProvider);
+ }
+
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return (adapter == IInternalEMFSelectionContext.class) ? getEMFContext() : null;
+ }
+
+ final IInternalEMFSelectionContext getEMFContext() {
+ if (emfContext == null) {
+ emfContext = new IInternalEMFSelectionContext.Default();
+ }
+ return emfContext;
+ }
+
+ @Override
+ protected URI getToken(Object object) {
+ return getEMFContext().getToken(object);
+ }
+
+ @Override
+ protected Object resolveToken(URI token) {
+ return getEMFContext().resolveToken(token);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFTreeViewerContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFTreeViewerContext.java
new file mode 100644
index 00000000000..a6f99008f06
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EMFTreeViewerContext.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ui.editor.reload;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+
+/**
+ * A convenient context object for {@link IEditorReloadListener}s to store in an {@link EditorReloadEvent} to capture and restore
+ * the expansion and selection state of nodes in an EMF-based tree viewer.
+ */
+public class EMFTreeViewerContext extends TreeViewerContext<URI> implements IAdaptable {
+
+ private IInternalEMFSelectionContext emfContext;
+
+ public EMFTreeViewerContext(AbstractTreeViewer viewer) {
+ super(viewer);
+ }
+
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return (adapter == IInternalEMFSelectionContext.class) ? getEMFContext() : null;
+ }
+
+ final IInternalEMFSelectionContext getEMFContext() {
+ if (emfContext == null) {
+ emfContext = new IInternalEMFSelectionContext.Default();
+ }
+ return emfContext;
+ }
+
+ @Override
+ protected URI getToken(Object object) {
+ return getEMFContext().getToken(object);
+ }
+
+ @Override
+ protected Object resolveToken(URI token) {
+ return getEMFContext().resolveToken(token);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadAdapter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadAdapter.java
new file mode 100644
index 00000000000..5015f26011e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadAdapter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.ui.editor.reload;
+
+
+
+/**
+ * Convenience superclass for selective implementation of editor reload call-backs.
+ */
+public class EditorReloadAdapter implements IEditorReloadListener {
+
+ public EditorReloadAdapter() {
+ super();
+ }
+
+ @Override
+ public void editorAboutToReload(EditorReloadEvent event) {
+ // Pass
+ }
+
+ @Override
+ public void editorReloaded(EditorReloadEvent event) {
+ // Pass
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadEvent.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadEvent.java
new file mode 100644
index 00000000000..c4d13f721b4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/EditorReloadEvent.java
@@ -0,0 +1,188 @@
+/*
+ * 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.ui.editor.reload;
+
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+
+/**
+ * The event object for notifications of each phase in the reloading of a {@linkplain IReloadableEditor reloadable editor}.
+ */
+public class EditorReloadEvent extends EventObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final int ABOUT_TO_RELOAD = 1;
+
+ public static final int RELOADED = 2;
+
+ private int type;
+
+ private transient Map<IEditorReloadListener, Object> context;
+
+ private transient IEditorReloadListener currentListener;
+
+ public EditorReloadEvent(IMultiDiagramEditor editor) {
+ super(editor);
+ }
+
+ public final IMultiDiagramEditor getEditor() {
+ return (IMultiDiagramEditor) getSource();
+ }
+
+ public final int getEventType() {
+ return type;
+ }
+
+ /**
+ * Puts some opaque representation of contextual state for the caller to retrieve later when an editor is {@linkplain IEditorReloadListener#editorReloaded(EditorReloadEvent) reloaded}.
+ * The canonical example of this usage is storing state such as selection, expanded tree nodes, etc. to restore after re-building a UI that
+ * depends on the reloaded editor. After the editor re-load completes and all listeners are notified of that, then all context objects are
+ * released. Any that implement the {@link IDisposableReloadContext} interface are disposed according to that protocol. This is done even if it
+ * happens that the editor re-load procedure cannot complete normally and the editor is forced to close without notifying the post-reload
+ * listeners.
+ *
+ * @param object
+ * some state to stash for later retrieval following the re-loading of the editor
+ *
+ * @return the previous context object, if any (there normally wouldn't be as each listener that is invoked has its own context storage
+ *
+ * @throws IllegalStateException
+ * on any attempt to invoke this method except during an {@link IEditorReloadListener#editorAboutToReload(EditorReloadEvent)} call-back
+ */
+ public Object putContext(Object object) {
+ checkContext(ABOUT_TO_RELOAD);
+
+ IInternalEMFSelectionContext emfContext = AdapterUtils.adapt(object, IInternalEMFSelectionContext.class, null);
+ if (emfContext != null) {
+ initContext(emfContext);
+ }
+
+ return context.put(currentListener, object);
+ }
+
+ /**
+ * Retrieves an opaque representation of contextual state that was previously {@linkplain #putContext(Object) put} by the caller.
+ *
+ * @return the previously stashed object, or {@code null} if none
+ *
+ * @throws IllegalStateException
+ * on any attempt to invoke this method except during an {@link IEditorReloadListener#editorReloaded(EditorReloadEvent)} call-back
+ */
+ public Object getContext() {
+ checkContext(RELOADED);
+ return context.get(currentListener);
+ }
+
+ private void initContext(IInternalEMFSelectionContext context) {
+ Supplier<ResourceSet> resourceSetSupplier = new Supplier<ResourceSet>() {
+
+ @Override
+ public ResourceSet get() {
+ try {
+ return getEditor().getServicesRegistry().getService(ModelSet.class);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ throw new IllegalStateException("Invalid service registry in editor"); //$NON-NLS-1$
+ }
+ }
+ };
+
+ context.setResourceSetSupplier(resourceSetSupplier);
+ }
+
+ protected final void checkContext(int phase) {
+ if (currentListener == null) {
+ throw new IllegalStateException("Not in an IEditorReloadListener call-back"); //$NON-NLS-1$
+ }
+
+ if (phase != this.type) {
+ throw new IllegalStateException(String.format("Not in '%s' listener call-back", (phase == ABOUT_TO_RELOAD) ? "editorAboutToReload" : "editorReloaded"));
+ }
+ }
+
+ public final void dispatchEditorAboutToReload(Iterable<? extends IEditorReloadListener> listeners) {
+ context = Maps.newHashMap();
+ type = ABOUT_TO_RELOAD;
+
+ for (Iterator<? extends IEditorReloadListener> iter = listeners.iterator(); iter.hasNext();) {
+ currentListener = iter.next();
+
+ try {
+ currentListener.editorAboutToReload(this);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in editor reload listener.", e); //$NON-NLS-1$
+ } finally {
+ currentListener = null;
+ }
+ }
+ }
+
+ public final void dispatchEditorReloaded(Iterable<? extends IEditorReloadListener> listeners) {
+ type = RELOADED;
+
+ for (Iterator<? extends IEditorReloadListener> iter = listeners.iterator(); iter.hasNext();) {
+ currentListener = iter.next();
+
+ try {
+ currentListener.editorReloaded(this);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in editor reload listener.", e); //$NON-NLS-1$
+ } finally {
+ currentListener = null;
+ }
+ }
+ }
+
+ public void dispose() {
+ if (context != null) {
+ Error error = null;
+
+ try {
+ for (IDisposableReloadContext next : Iterables.filter(context.values(), IDisposableReloadContext.class)) {
+ try {
+ next.dispose();
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in editor reload context disposal.", e); //$NON-NLS-1$
+ } catch (Error e) {
+ if (error == null) {
+ error = e;
+ }
+ Activator.log.error("Uncaught exception in editor reload context disposal.", e); //$NON-NLS-1$
+ }
+ }
+ } finally {
+ context = null;
+ }
+
+ if (error != null) {
+ throw error;
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IDisposableReloadContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IDisposableReloadContext.java
new file mode 100644
index 00000000000..8aff9ccf83b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IDisposableReloadContext.java
@@ -0,0 +1,23 @@
+/*
+ * 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.ui.editor.reload;
+
+/**
+ * Protocol implemented by {@link EditorReloadEvent} context objects that must be disposed when they are no longer needed.
+ *
+ * @see EditorReloadEvent#dispose()
+ */
+public interface IDisposableReloadContext {
+
+ void dispose();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IEditorReloadListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IEditorReloadListener.java
new file mode 100644
index 00000000000..2114d555152
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IEditorReloadListener.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ui.editor.reload;
+
+import java.util.EventListener;
+
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor;
+
+
+/**
+ * A protocol for notification of the phases of re-loading of an {@link IReloadableEditor}.
+ */
+public interface IEditorReloadListener extends EventListener {
+
+ /**
+ * Notifies that an editor is about to reload. Implementors may put stuff into the {@code event}'s {@link EditorReloadEvent#putContext(Object)
+ * context} to retrieve in an eventual {@linkplain #editorReloaded(EditorReloadEvent) }re-load} notification. The canonical example of this
+ * usage is storing state such as selection, expanded tree nodes, etc. to restore after re-building a UI that depends on the reloaded
+ * editor.
+ *
+ * @param event
+ * notification that an editor is going to re-load itself
+ */
+ void editorAboutToReload(EditorReloadEvent event);
+
+ /**
+ * Notifies that an editor has reloaded. Implementors may retrieve from the {@code event} any {@link EditorReloadEvent#getContext()
+ * context} that they put in {@linkplain #editorAboutToReload(EditorReloadEvent) before} the re-load.
+ *
+ * @param event
+ * notification that an editor has reloaded
+ */
+ void editorReloaded(EditorReloadEvent event);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IInternalEMFSelectionContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IInternalEMFSelectionContext.java
new file mode 100644
index 00000000000..f8bda865a97
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IInternalEMFSelectionContext.java
@@ -0,0 +1,109 @@
+/*
+ * 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.ui.editor.reload;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
+
+/**
+ * An internal interface provided (usually as an {@linkplain IAdaptable#getAdapter(Class) adapter}) by EMF-based {@linkplain SelectionContext
+ * selection contexts}.
+ */
+interface IInternalEMFSelectionContext {
+
+ void setResourceSetSupplier(Supplier<? extends ResourceSet> resourceSetSupplier);
+
+ URI getToken(Object object);
+
+ Object resolveToken(URI token);
+
+ class Default implements IInternalEMFSelectionContext {
+
+ Supplier<? extends ResourceSet> resourceSetSupplier;
+
+ Default() {
+ super();
+ }
+
+ @Override
+ public void setResourceSetSupplier(Supplier<? extends ResourceSet> resourceSetSupplier) {
+ this.resourceSetSupplier = Suppliers.memoize(resourceSetSupplier);
+ }
+
+ @Override
+ public URI getToken(Object object) {
+ return (object instanceof EObject) ? EcoreUtil.getURI((EObject) object) : null;
+ }
+
+ @Override
+ public Object resolveToken(URI token) {
+ ResourceSet rset = (resourceSetSupplier == null) ? null : resourceSetSupplier.get();
+ return (rset == null) ? null : rset.getEObject(token, true);
+ }
+
+ }
+
+ class Composite extends Default {
+
+ private final CompositeReloadContext composite;
+
+ Composite(CompositeReloadContext composite) {
+ super();
+
+ this.composite = composite;
+ }
+
+ @Override
+ public void setResourceSetSupplier(Supplier<? extends ResourceSet> resourceSetSupplier) {
+ super.setResourceSetSupplier(resourceSetSupplier);
+
+ for (Object next : composite.getReloadContexts()) {
+ IInternalEMFSelectionContext emfContext = AdapterUtils.adapt(next, IInternalEMFSelectionContext.class, null);
+ if (emfContext != null) {
+ // Pass along the memoizer so that we can all share it
+ emfContext.setResourceSetSupplier(this.resourceSetSupplier);
+ }
+ }
+ }
+ }
+
+ class Delegating extends Default {
+
+ private final DelegatingReloadContext delegating;
+
+ Delegating(DelegatingReloadContext delegating) {
+ super();
+
+ this.delegating = delegating;
+ }
+
+ @Override
+ public void setResourceSetSupplier(Supplier<? extends ResourceSet> resourceSetSupplier) {
+ super.setResourceSetSupplier(resourceSetSupplier);
+
+ IInternalEMFSelectionContext emfContext = AdapterUtils.adapt(delegating.getDelegate(), IInternalEMFSelectionContext.class, null);
+ if (emfContext != null) {
+ // Pass along the memoizer so that we can all share it
+ emfContext.setResourceSetSupplier(this.resourceSetSupplier);
+ }
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IReloadContextProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IReloadContextProvider.java
new file mode 100644
index 00000000000..f3449f59be9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/IReloadContextProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.ui.editor.reload;
+
+
+/**
+ * An adapter protocol for objects that can provide {@code context}s to be included in the
+ * re-load state of dependent parts in an {@link EditorReloadEvent}, for the purpose of
+ * restoring the state of those objects after re-load has completed.
+ */
+public interface IReloadContextProvider {
+
+ /**
+ * Creates an opaque token from which the receiver can be {@linkplain #restore(Object) restored} after the editor has reloaded.
+ *
+ * @return an opaque editor re-load context, or {@code null} if none is needed on this occasion (for example because the receiver
+ * is in its default state)
+ */
+ Object createReloadContext();
+
+ /**
+ * Reloads the receiver's state from a token previously {@linkplain #createReloadContext() provided}.
+ *
+ * @param reloadContext
+ * the opaque re-load context token
+ */
+ void restore(Object reloadContext);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/SelectionContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/SelectionContext.java
new file mode 100644
index 00000000000..15d58b5c4a1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/SelectionContext.java
@@ -0,0 +1,81 @@
+/*
+ * 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.ui.editor.reload;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+
+import com.google.common.collect.Lists;
+
+/**
+ * A convenient context object for {@link IEditorReloadListener}s to store in an {@link EditorReloadEvent} to capture and restore
+ * the selection state a selection provider;
+ *
+ * @param <V>
+ * the type of selection provider
+ * @param <T>
+ * the type of token used to restore the selection state
+ */
+public abstract class SelectionContext<V extends ISelectionProvider, T> {
+
+ private List<T> selection = Lists.newArrayList();
+
+ public SelectionContext(V structuredSelectionProvider) {
+ for (Object next : ((IStructuredSelection) structuredSelectionProvider.getSelection()).toList()) {
+ T token = token(next);
+ if (token != null) {
+ selection.add(token);
+ }
+ }
+ }
+
+ public void restore(V structuredSelectionProvider) {
+ List<Object> select = Lists.newArrayListWithCapacity(selection.size());
+ for (T next : selection) {
+ Object resolved = resolve(next);
+ if (resolved != null) {
+ select.add(resolved);
+ }
+ }
+ setSelection(structuredSelectionProvider, select);
+ }
+
+ T token(Object selectableElement) {
+ Object deresolved = deresolveSelectableElement(selectableElement);
+ return (deresolved == null) ? null : getToken(deresolved);
+ }
+
+ protected Object deresolveSelectableElement(Object selectableElement) {
+ return selectableElement;
+ }
+
+ protected abstract T getToken(Object object);
+
+ Object resolve(T token) {
+ Object deresolved = resolveToken(token);
+ return (deresolved == null) ? null : resolveSelectableElement(deresolved);
+ }
+
+ protected Object resolveSelectableElement(Object deresolved) {
+ return deresolved;
+ }
+
+ protected abstract Object resolveToken(T token);
+
+ protected void setSelection(V structuredSelectionProvider, List<?> selection) {
+ structuredSelectionProvider.setSelection(new StructuredSelection(selection));
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/TreeViewerContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/TreeViewerContext.java
new file mode 100644
index 00000000000..6d70788326c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/reload/TreeViewerContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ui.editor.reload;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+
+import com.google.common.collect.Lists;
+
+/**
+ * A convenient context object for {@link IEditorReloadListener}s to store in an {@link EditorReloadEvent} to capture and restore
+ * the expansion and selection state of nodes in a tree viewer.
+ */
+public abstract class TreeViewerContext<T> extends SelectionContext<AbstractTreeViewer, T> {
+
+ private List<T> expandedNodes = Lists.newArrayList();
+
+ public TreeViewerContext(AbstractTreeViewer viewer) {
+ super(viewer);
+
+ for (Object next : viewer.getExpandedElements()) {
+ T token = token(next);
+ if (token != null) {
+ expandedNodes.add(token);
+ }
+ }
+ }
+
+ @Override
+ public void restore(AbstractTreeViewer viewer) {
+ List<Object> expand = Lists.newArrayListWithCapacity(expandedNodes.size());
+ for (T next : expandedNodes) {
+ Object resolved = resolve(next);
+ if (resolved != null) {
+ expand.add(resolved);
+ }
+ }
+ setExpandedElements(viewer, expand);
+
+ super.restore(viewer);
+ }
+
+ @Override
+ protected void setSelection(AbstractTreeViewer viewer, List<?> selection) {
+ viewer.setSelection(new StructuredSelection(selection), true);
+ }
+
+ protected void setExpandedElements(AbstractTreeViewer viewer, Collection<?> toExpand) {
+ viewer.setExpandedElements(toExpand.toArray());
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/AbstractGetEditorIconQuery.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/AbstractGetEditorIconQuery.java
new file mode 100644
index 00000000000..9c02a4bf35d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/AbstractGetEditorIconQuery.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IPageIconsRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IPageIconsRegistryExtended;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageIconsRegistry;
+
+/**
+ *
+ * An abstract class to get the iconRegistery
+ *
+ */
+public abstract class AbstractGetEditorIconQuery {// we don't need to implements IJavaModelQuery here
+
+ /**
+ * the icon registry
+ */
+ private static IPageIconsRegistry editorRegistry;
+
+ /**
+ * Get the EditorRegistry used to create editor instances. This default
+ * implementation return the singleton eINSTANCE. This method can be
+ * subclassed to return another registry.
+ *
+ * @return the singleton eINSTANCE of editor registry
+ */
+ protected IPageIconsRegistryExtended getEditorRegistry(EObject context) {
+ try {
+ return (IPageIconsRegistryExtended) ServiceUtilsForEObject.getInstance().getService(IPageIconsRegistry.class, context);
+ } catch (Exception ex) {
+ // Skip
+ }
+ if (editorRegistry == null) {
+ editorRegistry = createEditorRegistry(context);
+ }
+ if (!(editorRegistry instanceof IPageIconsRegistryExtended)) {
+ throw new RuntimeException("The editor registry do not implement IPageIconsRegistryExtended");////$NON-NLS-1$
+ }
+ return (IPageIconsRegistryExtended) editorRegistry;
+ }
+
+ /**
+ * Return the EditorRegistry for nested editor descriptors. Subclass should
+ * implements this method in order to return the registry associated to the
+ * extension point namespace.
+ *
+ * @return the EditorRegistry for nested editor descriptors
+ */
+ protected IPageIconsRegistry createEditorRegistry(EObject context) {
+ try {
+ return ServiceUtilsForEObject.getInstance().getService(IPageIconsRegistry.class, context);
+ } catch (ServiceException e) {
+ // Not found, return an empty one which return null for each
+ // request.
+ return new PageIconsRegistry();
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorFactory.java
new file mode 100644
index 00000000000..a107a8e53ff
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorFactory.java
@@ -0,0 +1,57 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+
+/**
+ * Factory used to get the Icon associated to the editor used to render the
+ * specified pageIdentifier.
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface IEditorFactory {
+
+ /**
+ * Create the {@link IPageModel} for the specified identifier. TODO throw an
+ * exception encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * Object identifying an Editor.
+ * @return PageModel allowing to create the editor.
+ */
+ public IPageModel createIPageModel(Object pageIdentifier);
+
+ /**
+ * Return true if the factory can create an IPageModel for the specified
+ * pageIdentifier. Return false otherwise TODO throw an exception
+ * encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * The object representing the page to test
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier);
+
+ /**
+ * The ID of this factory
+ *
+ * @return
+ */
+ default String getFactoryID() {
+ return getClass().getName();
+ }
+
+ /**
+ * The display label of this factory
+ *
+ * @return
+ */
+ default String getLabel() {
+ return getClass().getSimpleName();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactory.java
new file mode 100644
index 00000000000..16ea36ce42b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactory.java
@@ -0,0 +1,64 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelMngr;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Factory used to create an {@link IPageModel} used by the {@link ISashWindowsContainer} to create an instance of the editor represented
+ * by the provided Object. Such factory is required by the {@link DiSashModelMngr}. It is called whenever the ISashWindowsContainer need
+ * to create an editor from an EObject representing this editor in the Di
+ * implementation of the {@link ISashWindowsContentProvider}
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface IEditorIconFactory {
+
+ /**
+ * Get the icon associated to the editor used to render the model. Model
+ * represent the top level object of a model editor. Can return a cached
+ * Image.
+ *
+ * @param pageIdentifier
+ * the pageIdentifier representing the Editor. This is usually
+ * the EObject used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image getEditorIcon(Object pageIdentifier);
+
+ /**
+ * Create the icon associated to the editor used to render the model. Model
+ * represent the top level object of a model editor. Always return a newly
+ * created Image.
+ *
+ * @param pageIdentifier
+ * the pageIdentifier representing the Editor. This is usually
+ * the EObject used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image createEditorIcon(Object pageIdentifier);
+
+ /**
+ * Return true if the factory can create an IPageModel for the specified
+ * pageIdentifier. Return false otherwise TODO throw an exception
+ * encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * The object representing the page to test
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier);
+
+ /**
+ * Dispose this factory
+ */
+ public void dispose();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactoryExtended.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactoryExtended.java
new file mode 100644
index 00000000000..52faed51ce4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IEditorIconFactoryExtended.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2011 Atos.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Atos - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+/**
+ *
+ * @author "Arthur Daussy <a href="mailto:arthur.daussy@atos.net">arthur.daussy@atos.net</a>"
+ *
+ */
+public interface IEditorIconFactoryExtended extends IEditorIconFactory {
+
+ /**
+ * Return the icon URL associated to the editor used to render the model. Model represent the top level
+ * object of a model editor.
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ public String getURLMainIcon(Object pageIdentifier);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistry.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistry.java
new file mode 100644
index 00000000000..4063f28288c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistry.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Registry used to get Icons associated to an editor.
+ *
+ * @author cedric dumoulin
+ */
+public interface IPageIconsRegistry {
+
+ /**
+ * Get the icon associated to the editor used to render the model. Model
+ * represent the top level object of a model editor.
+ *
+ * @param model
+ * the model representing the Editor. This is usually the EObject
+ * used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image getEditorIcon(Object model);
+
+ /**
+ * Dispose this registry
+ */
+ public void dispose();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistryExtended.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistryExtended.java
new file mode 100644
index 00000000000..a11b5f5e7ff
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/IPageIconsRegistryExtended.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2011 Atos Origin.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Atos Origin - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+/**
+ * Extends IPageIconsRegistry in order to offer a second methods which will give back the URL of the requested Icon
+ *
+ * @author "Arthur Daussy <a href="mailto:arthur.daussy@atos.net">arthur.daussy@atos.net</a>"
+ *
+ */
+public interface IPageIconsRegistryExtended extends IPageIconsRegistry {
+
+ /**
+ * Get the URL icon associated to the editor used to render the model. Model represent the top level
+ * object of a model editor.
+ *
+ * @param model
+ * @return {@link String} which represent the URL of the resource
+ */
+ public String getEditorURLIcon(Object model);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageIconsRegistry.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageIconsRegistry.java
new file mode 100644
index 00000000000..d60e8f71f96
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageIconsRegistry.java
@@ -0,0 +1,118 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Concrete implementation of the {@link IPageIconsRegistry}. This
+ * implementation allows to add and remove {@link IPageIconsRegistry}.
+ *
+ *
+ * @author cedric dumoulin
+ */
+public class PageIconsRegistry implements IPageIconsRegistryExtended {
+
+ /** list of registered icon factories */
+ protected List<IEditorIconFactory> pageIcons = new ArrayList<IEditorIconFactory>();
+
+ /**
+ * Constructor.
+ *
+ * @param editorFactoryRegistry
+ * @param servicesRegistry
+ */
+ public PageIconsRegistry() {
+
+ }
+
+ /**
+ * Walk each registered {@link IEditorFactory} to find the one handling the
+ * specified pageIdentifier. Call the corresponding method in the found
+ * pageIdentifier.
+ *
+ * TODO Throw an exception to report errors.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IPageModelFactory#createIPageModel(java.lang.Object)
+ */
+ @Override
+ public Image getEditorIcon(Object pageIdentifier) {
+
+ for (IEditorIconFactory factory : getPageIcons()) {
+ if (factory.isPageModelFactoryFor(pageIdentifier)) {
+ {
+ // return factory.getEditorIcon(pageIdentifier);
+ return factory.getEditorIcon(pageIdentifier);
+ }
+ }
+ }
+ // no editor found !
+ // TODO Throw an exception.
+ // throw new EditorNotFoundException("No editor registered for '" +
+ // pageIdentifier + "'.");
+ return null;
+ }
+
+ /**
+ * @return the editorFactories
+ */
+ protected List<IEditorIconFactory> getPageIcons() {
+ return pageIcons;
+ }
+
+ /**
+ * Add the specified {@link IEditorFactory}
+ *
+ * @param editorIconFactory
+ */
+ public void add(IEditorIconFactory editorIconFactory) {
+ // This should never happen
+ if (editorIconFactory == null) {
+ throw new RuntimeException("Parameter should not be null."); //$NON-NLS-1$
+ }
+
+ pageIcons.add(editorIconFactory);
+ }
+
+ /**
+ * Remove the specified {@link IEditorFactory}
+ *
+ * @param editorIconFactory
+ */
+ public void remove(IEditorIconFactory editorIconFactory) {
+ pageIcons.remove(editorIconFactory);
+ }
+
+ /**
+ * Return the path to the icon ressource.
+ *
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IPageIconsRegistryExtended#getEditorURLIcon(java.lang.Object)
+ *
+ * @param model
+ * @return
+ */
+ @Override
+ public String getEditorURLIcon(Object model) {
+ for (IEditorIconFactory factory : getPageIcons()) {
+ if (factory.isPageModelFactoryFor(model)) {
+ {
+ if (factory instanceof IEditorIconFactoryExtended) {
+ return ((IEditorIconFactoryExtended) factory).getURLMainIcon(model);
+ }
+ }
+ }
+ }
+ return "";
+ }
+
+ @Override
+ public void dispose() {
+ for (IEditorIconFactory factory : pageIcons) {
+ factory.dispose();
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageModelFactoryRegistry.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageModelFactoryRegistry.java
new file mode 100644
index 00000000000..32774bb7a25
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/PageModelFactoryRegistry.java
@@ -0,0 +1,165 @@
+/*****************************************************************************
+ * Copyright (c) 2009 - 2015 CEA LIST & LIFL
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ * Camille Letavernier (CEA LIST) - camille.letavernier@cea.fr - Bug 476625
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editorsfactory;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IPageModelFactory;
+import org.eclipse.papyrus.infra.ui.Activator;
+
+/**
+ * Concrete implementation of the {@link IPageModelFactory} required by the di
+ * implementation of {@link ISashWindowsContentProvider}. This implementation
+ * allows to add and remove {@link IEditorFactory}.
+ *
+ *
+ * @author cedric dumoulin
+ */
+public class PageModelFactoryRegistry implements IPageModelFactory {
+
+ /** ordered list of editor factories */
+ protected List<IEditorFactory> editorFactories = new ArrayList<IEditorFactory>();
+
+ /**
+ * Constructor.
+ *
+ * @param editorFactoryRegistry
+ * @param servicesRegistry
+ */
+ public PageModelFactoryRegistry() {
+
+ }
+
+ /**
+ * Walk each registered {@link IEditorFactory} to find the one handling the
+ * specified pageIdentifier. Call the corresponding method in the found
+ * pageIdentifier.
+ *
+ * TODO Throw an exception to report errors.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IPageModelFactory#createIPageModel(java.lang.Object)
+ */
+ @Override
+ public IPageModel createIPageModel(Object pageIdentifier) {
+ return createIPageModel(pageIdentifier, null);
+ }
+
+ /**
+ * Walk each registered {@link IEditorFactory} to find the one handling the
+ * specified pageIdentifier. Call the corresponding method in the found
+ * pageIdentifier.
+ *
+ * If several factories match the selected page, use the favorite editor.
+ * If the favorite editor is not available, use the priority mechanism
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IPageModelFactory#createIPageModel(java.lang.Object)
+ */
+ @Override
+ public IPageModel createIPageModel(Object pageIdentifier, String favoriteEditorID) {
+
+ IEditorFactory factory = getFactoryFor(pageIdentifier, favoriteEditorID);
+ if (factory == null) {
+ return null;
+ }
+ return factory.createIPageModel(pageIdentifier);
+ }
+
+ /**
+ * Returns the IEditorFactory for the given pageIdentifier.
+ *
+ * If several factories match the page identifier, use the favorite one
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ private IEditorFactory getFactoryFor(Object pageIdentifier, String favoriteEditorID) {
+ List<IEditorFactory> matchingFactories = new LinkedList<>();
+
+ for (IEditorFactory factory : getEditorFactories()) {
+ if (factory.isPageModelFactoryFor(pageIdentifier)) {
+ matchingFactories.add(factory);
+ }
+ }
+
+ if (matchingFactories.isEmpty()) {
+ return null;
+ } else if (matchingFactories.size() == 1) {
+ return matchingFactories.get(0);
+ } else if (favoriteEditorID != null) {
+ for (IEditorFactory matchingFactory : matchingFactories) {
+ if (favoriteEditorID.equals(matchingFactory.getFactoryID())) {
+ return matchingFactory;
+ }
+ }
+ }
+
+ return matchingFactories.get(0);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IPageModelFactory#getEditorIDsFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public Map<String, String> getEditorIDsFor(Object pageIdentifier) {
+ return getEditorFactories().stream()
+ .filter(f -> f.isPageModelFactoryFor(pageIdentifier))
+ .collect(Collectors
+ .toMap(
+ f -> f.getFactoryID(), f -> f.getLabel(), // key, value
+ (v1, v2) -> { // Conflict merger
+ Activator.log.warn(String.format("Several editors are declared with the same ID: '%s', '%s'", v1, v2));
+ return v1; // Any value
+ } ,
+ LinkedHashMap::new)); // HashMap Supplier
+ }
+
+ /**
+ * @return the editorFactories
+ */
+ protected List<IEditorFactory> getEditorFactories() {
+ return editorFactories;
+ }
+
+ /**
+ * Add the specified {@link IEditorFactory}
+ *
+ * @param editorFactory
+ */
+ public void add(IEditorFactory editorFactory) {
+ // This should never happen
+ if (editorFactory == null) {
+ throw new IllegalArgumentException("Parameter should not be null."); //$NON-NLS-1$
+ }
+
+ editorFactories.add(editorFactory);
+ }
+
+ /**
+ * Remove the specified {@link IEditorFactory}
+ *
+ * @param editorFactory
+ */
+ public void remove(IEditorFactory editorFactory) {
+ editorFactories.remove(editorFactory);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/anytype/AnyTypeEditorFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/anytype/AnyTypeEditorFactory.java
new file mode 100644
index 00000000000..137c3c533ef
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editorsfactory/anytype/AnyTypeEditorFactory.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (camille.letavernier@cea.fr) - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 392301
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.editorsfactory.anytype;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.xml.type.AnyType;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IComponentModel;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.infra.ui.extension.diagrameditor.AbstractEditorFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * An EditorFactory for "AnyType", i.e. EObject deserialized from unknown Packages
+ *
+ * Allows recovery and manipulation of models containing optional EMF components
+ *
+ * @author Camille Letavernier
+ */
+public class AnyTypeEditorFactory extends AbstractEditorFactory {
+
+ public AnyTypeEditorFactory() {
+ super(null, "AnyTypeHandler");
+ }
+
+ @Override
+ public IPageModel createIPageModel(Object pageIdentifier) {
+
+ final AnyType anyTypeModel = (AnyType) pageIdentifier;
+
+ return new IComponentModel() {
+
+ private AnyType anyType = anyTypeModel;
+
+ @Override
+ public void dispose() {
+ // Pass. The tab icon is a workbench-shared image
+ }
+
+ @Override
+ public String getTabTitle() {
+ EClass eClass = anyType.eClass();
+ String label;
+ if (eClass == null) {
+ label = "component";
+ } else {
+ label = eClass.getName();
+ }
+ return "Missing " + label;
+ }
+
+ private String getTypeLabel() {
+ EClass eClass = anyType.eClass();
+ String className = eClass == null ? "None" : eClass.getName();
+ return className;
+ }
+
+ private String getNsURI() {
+ EClass eClass = anyType.eClass();
+ EPackage ePackage = eClass == null ? null : eClass.getEPackage();
+ String ePackageName = ePackage == null ? "None" : ePackage.getNsURI();
+
+ return ePackageName;
+ }
+
+ public Image getComponentIcon() {
+ return Display.getDefault().getSystemImage(SWT.ICON_WARNING);
+ }
+
+ @Override
+ public Image getTabIcon() {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK);
+ }
+
+ @Override
+ public Object getRawModel() {
+ return anyType;
+ }
+
+ public String getErrorText() {
+ String typeLabel = getTypeLabel();
+ String packageURI = getNsURI();
+ String message = "A component is missing. The following Model cannot be loaded: " + typeLabel + " (from " + packageURI + ")\n";
+ message += "Changes to the model won't be reflected in this editor. This editor will be saved in the current state, i.e. without any data loss. ";
+ message += "However, this may result in an inconsistent state of this editor when the missing component will be restored\n";
+ return message;
+ }
+
+ @Override
+ public Composite createPartControl(Composite parent) {
+ Composite tabComposite = new Composite(parent, SWT.NONE);
+ tabComposite.setLayout(new GridLayout(2, false));
+
+ Image componentIcon = getComponentIcon();
+ if (componentIcon != null) {
+ Label errorImageLabel = new Label(tabComposite, SWT.NONE);
+ errorImageLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+ errorImageLabel.setImage(componentIcon);
+ }
+
+ Label label = new Label(tabComposite, SWT.WRAP);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ label.setText(getErrorText());
+
+ return tabComposite;
+ }
+ };
+ }
+
+ @Override
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ return pageIdentifier instanceof AnyType;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/ICreationCondition.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/ICreationCondition.java
new file mode 100644
index 00000000000..035cfbfda70
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/ICreationCondition.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2009 ATOS ORIGIN.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Tristan Faure (ATOS ORIGIN) tristan.faure@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.commands;
+
+import org.eclipse.emf.ecore.EObject;
+
+public interface ICreationCondition {
+
+ /**
+ * This method returns true if the diagram creation is allowed
+ *
+ * @param selectedElement
+ * the element where the diagram is provided
+ * @return true if the diagram can be created
+ */
+ boolean create(EObject selectedElement);
+
+ /**
+ * set the command ID in order to take account the environment in order to
+ * create a diagram
+ *
+ * @param commandID
+ */
+ public void setCommand(String commandID);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/IModelCreationCommand.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/IModelCreationCommand.java
new file mode 100644
index 00000000000..8b7f371b28e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/IModelCreationCommand.java
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tatiana Fesenko (CEA LIST) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.commands;
+
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+
+/**
+ * The Interface IModelCreationCommand.
+ */
+public interface IModelCreationCommand {
+
+ /**
+ * Creates the model.
+ *
+ * @param modelSet
+ * the modelSet set
+ */
+ void createModel(final ModelSet modelSet);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/PerspectiveContextDependence.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/PerspectiveContextDependence.java
new file mode 100644
index 00000000000..0c8b0a9d9fe
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/commands/PerspectiveContextDependence.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.commands;
+
+import org.eclipse.emf.ecore.EObject;
+
+//FIXME Refactoring Juno : I don't know how to migrate this code
+public class PerspectiveContextDependence implements ICreationCondition {
+
+ protected String commandID = null;
+
+ public PerspectiveContextDependence() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean create(EObject selectedElement) {
+ // FIXME Refactoring Juno : I don't know how to migrate this code
+ // // Get the perspective
+ // Perspective perspective = ((WorkbenchPage)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()).getActivePerspective();
+ // // look for the perspective
+ // // verify if the command has to be displayed
+ // if(perspective.getHiddenMenuItems().contains(commandID) && perspective.getHiddenToolbarItems().contains(commandID)) {
+ // return false;
+ // }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setCommand(String commandID) {
+ this.commandID = commandID;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/AbstractEditorFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/AbstractEditorFactory.java
new file mode 100644
index 00000000000..89ace2da204
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/AbstractEditorFactory.java
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory;
+
+/**
+ * Abstract base class for Factory of editors. See {@link IEditorFactory}.
+ *
+ *
+ * @author Remi Schnekenburger
+ * @author Patrick Tessier
+ * @author cedric dumoulin
+ */
+public abstract class AbstractEditorFactory implements IPluggableEditorFactory {
+
+ /**
+ * Expected Class of the diagram to create.
+ */
+ private Class<?> diagramClass;
+
+ /** Expected diagram type (@see {@link Diagram#getType()}) */
+ private String expectedType;
+
+ /**
+ * EditorDescriptor associated to the factory. TODO : Maybe use individual
+ * setters to set the requested data (ContributorId and Icon).
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * ServiceRegistry that can be provided to created editors.
+ */
+ private ServicesRegistry serviceRegistry;
+
+ /**
+ * Creates a new AbstractEditorFactory.
+ *
+ * @param diagramClass
+ * expected Class of the diagram to create.
+ * @param expectedType
+ * expected diagram type (@see {@link Diagram#getType()})
+ */
+ public AbstractEditorFactory(Class<?> diagramClass, String expectedType) {
+ assert (expectedType != null);
+ this.diagramClass = diagramClass;
+ this.expectedType = expectedType;
+ }
+
+ /**
+ * Initialize the factory with useful Classes.
+ *
+ * @param serviceRegistry
+ * Service registry that will be provided to created editor.
+ * @param editorDescriptor
+ * Descriptor containing data from the Eclipse Extension.
+ */
+ @Override
+ public void init(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor) {
+ this.editorDescriptor = editorDescriptor;
+ this.serviceRegistry = serviceRegistry;
+
+ }
+
+ /**
+ * @return the serviceRegistry
+ */
+ public ServicesRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ /**
+ * Returns the expected class for the diagram implementation
+ *
+ * @return the expected class for the diagram implementation
+ */
+ public Class<?> getDiagramClass() {
+ return diagramClass;
+ }
+
+ /**
+ * Returns the expected type of the diagram
+ *
+ * @return the expected diagram type (@see {@link Diagram#getType()})
+ */
+ public String getExpectedType() {
+ return expectedType;
+ }
+
+ /**
+ * @return the editorDescriptor
+ */
+ public EditorDescriptor getEditorDescriptor() {
+ return editorDescriptor;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptor.java
new file mode 100644
index 00000000000..d7aa6d558eb
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptor.java
@@ -0,0 +1,168 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * This descriptor describes a nested diagram. It is used by MultiDiagramEditor
+ * to know about the nested diagram. It is fill by an extension.
+ *
+ * @author Cedric Dumoulin
+ *
+ */
+public class EditorDescriptor {
+
+ /**
+ * Editor factory implementation class.
+ */
+ private Class<IPluggableEditorFactory> editorFactoryClass;
+
+ /**
+ * EditorActionBarContributor Id used to search the
+ * EditorActionBarContributor requested by the editor.
+ */
+ private String actionBarContributorId;
+
+ /**
+ * The icon representing the diagram
+ */
+ private ImageDescriptor icon;
+
+ /**
+ * Resource path to the icon
+ */
+ private String iconPath;
+
+ /**
+ * The order of this factory. Used when several factories match the same element (Diagram...)
+ * The lower the order, the higher the priority of this factory
+ */
+ private int order;
+
+ /**
+ * Constructor.
+ */
+ public EditorDescriptor() {
+
+ }
+
+ /**
+ *
+ * @param attribute
+ */
+ public void setActionBarContributorId(String actionBarContributorId) {
+ this.actionBarContributorId = actionBarContributorId;
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.extension.diagrameditor.IEditorDescriptor#getActionBarContributorId()
+ * @return
+ *
+ */
+ public String getActionBarContributorId() {
+ return actionBarContributorId;
+ }
+
+ /**
+ * get the editor icon path
+ *
+ * @return the editor icon path
+ */
+ public ImageDescriptor getIcon() {
+ return icon;
+ }
+
+ /**
+ * set the editor icon
+ *
+ * @param icon
+ * the icon path
+ */
+ public void setIcon(ImageDescriptor icon) {
+ this.icon = icon;
+ }
+
+ /**
+ * get the class of the editor factory
+ *
+ * @return the class of the editor
+ */
+ public Class<IPluggableEditorFactory> getEditorFactoryClass() {
+ return editorFactoryClass;
+ }
+
+ /**
+ * set the editor facoty to this descriptor
+ *
+ * @param editorFactoryClass
+ * the class that represents the editor factory
+ */
+ public void setEditorFactoryClass(Class<IPluggableEditorFactory> editorFactoryClass) {
+ this.editorFactoryClass = editorFactoryClass;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ if (editorFactoryClass == null || editorFactoryClass.getName() == null) {
+ return "[nestedEditor editorFactory:" + editorFactoryClass + "(null)]";
+ }
+ return "[nestedEditor editorFactory:" + editorFactoryClass.getName() + "]";
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ /**
+ * Set the URL of the Icon
+ *
+ * @param iconPath
+ * path of the Icon
+ */
+ public void setIconURL(String iconPath) {
+ this.iconPath = iconPath;
+ }
+
+ /**
+ * Get the URL of the based images
+ *
+ * @return the path of the mai image. can return null if this property is not set
+ */
+ public String getIconURL() {
+ return iconPath;
+ }
+
+ /**
+ * set the Icon thanks to a {@link IConfigurationElement} and {@link String}which represent the path of the Icon
+ *
+ * @param element
+ * @param iconPath
+ */
+ public void setIcon(IConfigurationElement element, String iconPath, String pluginID) {
+ setIcon(AbstractUIPlugin.imageDescriptorFromPlugin(element.getNamespaceIdentifier(), iconPath));
+ setIconURL(element.getNamespaceIdentifier() + '/' + iconPath);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptorExtensionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptorExtensionFactory.java
new file mode 100644
index 00000000000..8d57b2fe3ab
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorDescriptorExtensionFactory.java
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import static org.eclipse.papyrus.infra.core.Activator.log;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.infra.core.extension.BadNameExtensionException;
+import org.eclipse.papyrus.infra.core.extension.ExtensionException;
+import org.eclipse.papyrus.infra.core.extension.ExtensionUtils;
+import org.eclipse.papyrus.infra.ui.Activator;
+
+/**
+ * A factory used to create editor descriptor object from Eclipse extensions points elements.
+ *
+ * @author Cedric Dumoulin
+ * @author Patrick Tessier
+ */
+public class EditorDescriptorExtensionFactory extends ExtensionUtils {
+
+ /** singleton eINSTANCE of this class */
+ public final static EditorDescriptorExtensionFactory eINSTANCE = new EditorDescriptorExtensionFactory();
+
+ /** constant for the editor diagram **/
+ public final static String EDITOR_DIAGRAM_EXTENSIONPOINT = "editorDiagram";
+
+ /** constant for the attribute factoryClass **/
+ public final static String FACTORYCLASS_ATTRIBUTE = "factoryClass";
+
+ /** constant for the attribute contextId **/
+ public final static String ACTIONBARCONTRIBUTORID_ATTRIBUTE = "actionBarContributorId";
+
+ /** constant for the attribute icon **/
+ public final static String ICON_ATTRIBUTE = "icon";
+
+ /** constant for the order attribute */
+ public final static String ORDER_ATTRIBUTE = "order";
+
+ /**
+ * @return the eINSTANCE
+ */
+ public static EditorDescriptorExtensionFactory getInstance() {
+ return eINSTANCE;
+ }
+
+ /**
+ * Create a descriptor instance corresponding to the ConfigurationElement.
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @return a nestedEditorDescriptor structure that contains information to create diagrams
+ * @throws BadNameExtensionException
+ */
+ @SuppressWarnings("unchecked")
+ public EditorDescriptor createNestedEditorDescriptor(IConfigurationElement element) throws ExtensionException {
+ EditorDescriptor res;
+
+ checkTagName(element, EDITOR_DIAGRAM_EXTENSIONPOINT);
+
+ res = new EditorDescriptor();
+ res.setEditorFactoryClass((Class<IPluggableEditorFactory>) parseClass(element, FACTORYCLASS_ATTRIBUTE, EDITOR_DIAGRAM_EXTENSIONPOINT));
+ res.setActionBarContributorId(element.getAttribute(ACTIONBARCONTRIBUTORID_ATTRIBUTE));
+
+ int order = 0; // Default
+ try {
+ String orderAttribute = element.getAttribute(ORDER_ATTRIBUTE);
+ if (orderAttribute != null) {
+ order = Integer.parseInt(orderAttribute);
+ }
+ } catch (NumberFormatException ex) {
+ Activator.log.warn("Invalid order provided by " + element.getContributor() + ". Order should be an integer value"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ res.setOrder(order);
+
+ String iconPath = element.getAttribute(ICON_ATTRIBUTE);
+ if (iconPath != null) {
+ /** Implementation which set the icon and register the complete URL of the icon : Bug eclipse 358732 */
+ res.setIcon(element, iconPath, Activator.PLUGIN_ID);
+
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Read editor descriptor " + res); //$NON-NLS-1$
+ }
+ return res;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorFactoryProxy.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorFactoryProxy.java
new file mode 100644
index 00000000000..8a80509bda2
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorFactoryProxy.java
@@ -0,0 +1,137 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory;
+
+/**
+ * A proxy implementation of {@link IEditorFactory} used to do lazy
+ * instantiation of concrete {@link IPluggableEditorFactory}. This class is used
+ * by the {@link PluggableEditorFactoryReader}
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class EditorFactoryProxy implements IEditorFactory {
+
+ /**
+ * The concrete implementation.
+ */
+ private IPluggableEditorFactory editorFactory;
+
+ /**
+ * EditorDescriptor associated to the factory.
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * ServiceRegistry that can be provided to created editors.
+ */
+ private ServicesRegistry serviceRegistry;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param editorDescriptor
+ */
+ public EditorFactoryProxy(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor) {
+ this.serviceRegistry = serviceRegistry;
+ this.editorDescriptor = editorDescriptor;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory#createIPageModel(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public IPageModel createIPageModel(Object pageIdentifier) {
+ try {
+ return getEditorFactory().createIPageModel(pageIdentifier);
+ } catch (Exception ex) {
+ // An error occurred in a contribution. Do not use this factory
+ return null;
+ }
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory#isPageModelFactoryFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ try {
+ return getEditorFactory().isPageModelFactoryFor(pageIdentifier);
+ } catch (Exception ex) {
+ // An error occurred in a contribution. Do not use this factory
+ return false;
+ }
+ }
+
+ /**
+ * @return the editorFactory
+ */
+ protected IPluggableEditorFactory getEditorFactory() {
+
+ if (editorFactory == null) {
+ editorFactory = createEditorFactory();
+ }
+
+ return editorFactory;
+
+ }
+
+ /**
+ * Create an instance of IPluggableEditorFactory as described in the
+ * editorDescriptor. TODO let propagate the exceptions.
+ *
+ * @return
+ */
+ private IPluggableEditorFactory createEditorFactory() {
+ // Create the requested class.
+ try {
+ editorFactory = editorDescriptor.getEditorFactoryClass().newInstance();
+ // Set the descriptor. USed by the factory to get the ActionBarId
+ // and Icon
+ editorFactory.init(serviceRegistry, editorDescriptor);
+ return editorFactory;
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory#getFactoryID()
+ *
+ * @return
+ */
+ @Override
+ public String getFactoryID() {
+ return getEditorFactory().getFactoryID();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory#getLabel()
+ *
+ * @return
+ */
+ @Override
+ public String getLabel() {
+ return getEditorFactory().getLabel();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorIconFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorIconFactory.java
new file mode 100644
index 00000000000..94038633af4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorIconFactory.java
@@ -0,0 +1,152 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IEditorIconFactoryExtended;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A factory used to create the Icon associated to an editor TODO Lets have a
+ * common ancestor for {@link EditorIconFactory} and {@link EditorFactoryProxy}
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class EditorIconFactory implements IEditorIconFactoryExtended {
+
+ /**
+ * The concrete implementation.
+ */
+ private IPluggableEditorFactory editorFactory;
+
+ /**
+ * EditorDescriptor associated to the factory.
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * Cached image for reuse.
+ */
+ protected Image cachedImage;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param editorDescriptor
+ */
+ public EditorIconFactory(EditorDescriptor editorDescriptor) {
+ this.editorDescriptor = editorDescriptor;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorIconFactory#getEditorIcon(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public Image getEditorIcon(Object pageIdentifier) {
+
+ if (cachedImage == null) {
+ cachedImage = createEditorIcon(pageIdentifier);
+ }
+
+ return cachedImage;
+ }
+
+ /**
+ * Create an Image associated to the editor used to render the specified
+ * pageIdentifier
+ *
+ * @return
+ */
+ @Override
+ public Image createEditorIcon(Object pageIdentifier) {
+ ImageDescriptor imageDescriptor = editorDescriptor.getIcon();
+ if (imageDescriptor == null) {
+ return null;
+ }
+ Image image = imageDescriptor.createImage();
+ return image;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory#isPageModelFactoryFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ return getEditorFactory().isPageModelFactoryFor(pageIdentifier);
+ }
+
+ /**
+ * @return the editorFactory
+ */
+ protected IPluggableEditorFactory getEditorFactory() {
+
+ if (editorFactory == null) {
+ editorFactory = createEditorFactory();
+ }
+
+ return editorFactory;
+
+ }
+
+ /**
+ * Create an instance of IPluggableEditorFactory as described in the
+ * editorDescriptor. TODO let propagate the exceptions.
+ *
+ * @return
+ */
+ private IPluggableEditorFactory createEditorFactory() {
+ // Create the requested class.
+ try {
+ editorFactory = editorDescriptor.getEditorFactoryClass().newInstance();
+ // Set the descriptor. USed by the factory to get the ActionBarId
+ // and Icon
+ // editorFactory.init(serviceRegistry, editorDescriptor);
+ return editorFactory;
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /**
+ * Return the URL of the main icon used to create this icon
+ *
+ * @see org.eclipse.papyrus.infra.ui.editorsfactory.IEditorIconFactory#getURLMainIcon(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public String getURLMainIcon(Object pageIdentifier) {
+ return editorDescriptor.getIconURL();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Dispose the cached image
+ */
+ @Override
+ public void dispose() {
+ if (cachedImage != null) {
+ cachedImage.dispose();
+ cachedImage = null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorNotFoundException.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorNotFoundException.java
new file mode 100644
index 00000000000..f0e189ae4e1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/EditorNotFoundException.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+/**
+ * Editor was not found.
+ *
+ * @author dumoulin
+ *
+ */
+@SuppressWarnings("serial")
+public class EditorNotFoundException extends MultiDiagramException {
+
+ /**
+ *
+ */
+ public EditorNotFoundException() {
+ }
+
+ /**
+ * @param arg0
+ */
+ public EditorNotFoundException(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ */
+ public EditorNotFoundException(Throwable arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public EditorNotFoundException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/IPluggableEditorFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/IPluggableEditorFactory.java
new file mode 100644
index 00000000000..87f1cde5d2b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/IPluggableEditorFactory.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.IEditorFactory;
+
+/**
+ * This interface should be implemented by Editor Factories that can be declared
+ * as Eclipse extension. It extends the {@link IEditorFactory} by adding methods
+ * to initialize the factory with multieditor ServiceRegistry and associated
+ * editor data.
+ *
+ * @author C�dric Dumoulin
+ *
+ */
+public interface IPluggableEditorFactory extends IEditorFactory {
+
+ /**
+ * Initialize the factory with useful Classes.
+ *
+ * @param serviceRegistry
+ * Service registry that will be provided to created editor.
+ * @param editorDescriptor
+ * Descriptor containing data from the Eclipse Extension.
+ */
+ public void init(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/MultiDiagramException.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/MultiDiagramException.java
new file mode 100644
index 00000000000..fd6a89ff037
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/MultiDiagramException.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+/**
+ * Root Exception of MultiDiagram exception
+ *
+ * @author dumoulin
+ *
+ */
+@SuppressWarnings("serial")
+public class MultiDiagramException extends Exception {
+
+ /**
+ *
+ */
+ public MultiDiagramException() {
+ }
+
+ /**
+ * @param arg0
+ */
+ public MultiDiagramException(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ */
+ public MultiDiagramException(Throwable arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public MultiDiagramException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/PluggableEditorFactoryReader.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/PluggableEditorFactoryReader.java
new file mode 100644
index 00000000000..75dc1d7cc96
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/extension/diagrameditor/PluggableEditorFactoryReader.java
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.extension.diagrameditor;
+
+import static org.eclipse.papyrus.infra.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.infra.core.extension.ExtensionException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageIconsRegistry;
+import org.eclipse.papyrus.infra.ui.editorsfactory.PageModelFactoryRegistry;
+
+/**
+ * This reader is used to read PluggableEditorFactory from the Eclipse extension
+ * declarations. It can be used to populate an {@link PageModelFactoryRegistry}.
+ */
+public class PluggableEditorFactoryReader {
+
+ /** ordered list of editor descriptors */
+ protected List<EditorDescriptor> editorDescriptors;
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusDiagram";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /** indicates if extension is loaded or not */
+ private boolean isExtensionLoaded = false;
+
+ /**
+ * Create a new Registry reading extension from the specified namespace. The
+ * namespace is usually the name of the plugin owning the registry.
+ *
+ * @param extensionPointNamespace
+ */
+ public PluggableEditorFactoryReader(String extensionPointNamespace) {
+ super();
+ this.extensionPointNamespace = extensionPointNamespace;
+ editorDescriptors = new ArrayList<EditorDescriptor>();
+ }
+
+ /**
+ * Populate the provided {@link PageModelFactoryRegistry} with {@link IPluggableEditorFactory} read from Eclipse extension declarations.
+ * For each declared editor, create a proxy encapsulating the real
+ * EditorFactory. Then the proxy is added to the PageModelFactoryRegistry.
+ *
+ * @param pageModelFactoryRegistry
+ * The object to populate
+ * @param serviceRegistry
+ * ServiceRegistry provided to newly instantiated {@link IPluggableEditorFactory}.
+ */
+ public void populate(PageModelFactoryRegistry pageModelFactoryRegistry, ServicesRegistry serviceRegistry) {
+
+ for (EditorDescriptor desc : getEditorDescriptors()) {
+
+ // Create and add a proxy encapsulating the EditorFactory.
+ pageModelFactoryRegistry.add(new EditorFactoryProxy(serviceRegistry, desc));
+ }
+ }
+
+ /**
+ * Populate the provided {@link PageIconsRegistry} with icons read from
+ * Eclipse extension declarations. For each declared editor, create a {@link EditorIconFactory}.
+ *
+ * @param pageModelFactoryRegistry
+ * The object to populate
+ * @param serviceRegistry
+ * ServiceRegistry provided to newly instantiated {@link IPluggableEditorFactory}.
+ */
+ public void populate(PageIconsRegistry registry) {
+
+ for (EditorDescriptor desc : getEditorDescriptors()) {
+
+ // Create and add a proxy encapsulating the EditorFactory.
+ registry.add(new EditorIconFactory(desc));
+ }
+ }
+
+ /**
+ * Get the list of editor descriptor.
+ *
+ * @return the list of editor descriptor.
+ */
+ public List<EditorDescriptor> getEditorDescriptors() {
+ if (!isExtensionLoaded) {
+ isExtensionLoaded = true;
+ initializeEditorDescriptors();
+ }
+ return editorDescriptors;
+ }
+
+ /**
+ * Read editor descriptors from extension points.
+ */
+ private void initializeEditorDescriptors() {
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+
+ for (IConfigurationElement ele : configElements) {
+ EditorDescriptor desc;
+ try {
+ if (EditorDescriptorExtensionFactory.EDITOR_DIAGRAM_EXTENSIONPOINT.equals(ele.getName())) {
+ desc = EditorDescriptorExtensionFactory.eINSTANCE.createNestedEditorDescriptor(ele);
+ editorDescriptors.add(desc);
+ }
+ } catch (ExtensionException e) {
+ log.error("Initialization editor problem ", e); //$NON-NLS-1$
+ }
+ }
+
+ Collections.sort(editorDescriptors, (ed1, ed2) -> Integer.compare(ed1.getOrder(), ed2.getOrder()));
+
+ if (log.isDebugEnabled()) {
+ log.debug("Read " + editorDescriptors.size() + " editor descriptors from Eclipse extensions"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "EditorFactoryRegistry: " + editorDescriptors.toString();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/PageLayoutStorageState.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/PageLayoutStorageState.java
new file mode 100644
index 00000000000..6e604a90914
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/PageLayoutStorageState.java
@@ -0,0 +1,164 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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.ui.internal.commands;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.jface.commands.ToggleState;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The boolean toggle state of the private page layout storage menu item.
+ */
+public class PageLayoutStorageState extends ToggleState implements IPartListener, PropertyChangeListener {
+
+ private IPartService partService = null;
+
+ private Reference<IMultiDiagramEditor> activeEditor;
+
+ public PageLayoutStorageState() {
+ super();
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+
+ if (window != null) {
+ partService = window.getPartService();
+ if (partService != null) {
+ partService.addPartListener(this);
+ update(partService.getActivePart());
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (partService != null) {
+ partService.removePartListener(this);
+ }
+
+ super.dispose();
+ }
+
+ @Override
+ public void partDeactivated(IWorkbenchPart part) {
+ if ((activeEditor != null) && (activeEditor.get() == part)) {
+ update(null);
+ }
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPart part) {
+ update(part);
+ }
+
+ private void update(IWorkbenchPart part) {
+ // Default state is private storage
+ boolean state = true;
+
+ unhookSashModelListener();
+
+ activeEditor = null;
+
+ if (part instanceof IMultiDiagramEditor) {
+ IMultiDiagramEditor editor = (IMultiDiagramEditor) part;
+ activeEditor = new WeakReference<>(editor);
+ state = isPrivateLayout(editor);
+ }
+
+ hookSashModelListener();
+
+ // Fires notification if changed from previous state
+ setValue(state);
+ }
+
+ // I am a computed value, actually
+ @Override
+ public Object getValue() {
+ IMultiDiagramEditor editor = (activeEditor == null) ? null : activeEditor.get();
+ return (editor != null) ? isPrivateLayout(editor) : super.getValue();
+ }
+
+ boolean isPrivateLayout(IMultiDiagramEditor editor) {
+ ModelSet modelSet = (ModelSet) editor.getAdapter(EditingDomain.class).getResourceSet();
+ SashModel sashModel = SashModelUtils.getSashModel(modelSet);
+
+ // The default is private layout
+ return (sashModel == null) || !sashModel.isLegacyMode();
+ }
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPart part) {
+ // Pass
+ }
+
+ @Override
+ public void partClosed(IWorkbenchPart part) {
+ // Pass
+ }
+
+ @Override
+ public void partOpened(IWorkbenchPart part) {
+ // Pass
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getSource() instanceof SashModel) {
+ switch (evt.getPropertyName()) {
+ case SashModel.PROPERTY_LEGACY_MODE:
+ setValue(!(Boolean) evt.getNewValue());
+ break;
+ }
+ }
+ }
+
+ private SashModel getSashModel() {
+ SashModel result = null;
+
+ if (activeEditor != null) {
+ IMultiDiagramEditor editor = activeEditor.get();
+ if (editor != null) {
+ result = SashModelUtils.getSashModel(editor.getServicesRegistry());
+ }
+ }
+
+ return result;
+ }
+
+ private void unhookSashModelListener() {
+ SashModel sash = getSashModel();
+ if (sash != null) {
+ sash.removePropertyChangeListener(SashModel.PROPERTY_LEGACY_MODE, this);
+ }
+ }
+
+ private void hookSashModelListener() {
+ SashModel sash = getSashModel();
+ if (sash != null) {
+ sash.addPropertyChangeListener(SashModel.PROPERTY_LEGACY_MODE, this);
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/SashLayoutCommandFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/SashLayoutCommandFactory.java
new file mode 100644
index 00000000000..61c931b1ec4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/SashLayoutCommandFactory.java
@@ -0,0 +1,226 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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.ui.internal.commands;
+
+import java.util.ArrayList;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.sashwindows.di.PageRef;
+import org.eclipse.papyrus.infra.core.sashwindows.di.SashModel;
+import org.eclipse.papyrus.infra.core.sashwindows.di.SashWindowsMngr;
+import org.eclipse.papyrus.infra.core.sashwindows.di.TabFolder;
+import org.eclipse.papyrus.infra.core.sashwindows.di.util.DiUtils;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+
+/**
+ * A factory for commands that manipulate the configuration of the sash editor layout.
+ */
+public class SashLayoutCommandFactory {
+ private final IMultiDiagramEditor editor;
+
+ public SashLayoutCommandFactory(IMultiDiagramEditor editor) {
+ super();
+
+ this.editor = editor;
+ }
+
+ /**
+ * Creates a command that toggles whether the sash model is stored in the private
+ * workspace metadata area or in the shared {@code *.di} file.
+ *
+ * @return a toggle command for the private layout storage
+ */
+ public Command createTogglePrivateLayoutCommand() {
+ Command result = UnexecutableCommand.INSTANCE;
+
+ ModelSet modelSet = (ModelSet) editor.getAdapter(EditingDomain.class).getResourceSet();
+ org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel sashModel = SashModelUtils.getSashModel(modelSet);
+ if (sashModel != null) {
+ result = new AbstractToggleCommand("Toggle Private Editor Layout") {
+ private Command toggleRestoreActivePage;
+
+ {
+ // If we are toggling off private mode, make sure that we stop
+ // tracking the active page selection if we were tracking it.
+ // And remember that for undo
+ if (!sashModel.isLegacyMode()) {
+ SashWindowsMngr sash = DiUtils.lookupSashWindowsMngr(sashModel.getResource());
+ if ((sash != null) && (sash.getSashModel() != null) && sash.getSashModel().isRestoreActivePage()) {
+ toggleRestoreActivePage = createToggleRestoreActivePageCommand();
+ }
+ }
+ }
+
+ @Override
+ public void execute() {
+ // First, if we need to toggle restoring the active page, do that
+ if ((toggleRestoreActivePage != null) && toggleRestoreActivePage.canExecute()) {
+ toggleRestoreActivePage.execute();
+ }
+
+ SashWindowsMngr toMove = DiUtils.lookupSashWindowsMngr(sashModel.getResource());
+
+ // We don't record changes in the sash model for undo/redo,
+ // so we cannot assume that any changes to the current page selections
+ // are undoable in the usual way
+ if (!sashModel.isLegacyMode()) {
+ Resource sashResource = toMove.eResource();
+ URI sharedURI = sashModel.getSharedResourceURI();
+
+ // Move the contents into the DI model. If the DI resource isn't loaded,
+ // give up because something is seriously wrong in that case
+ Resource diResource = modelSet.getResource(sharedURI, false);
+ if ((diResource != null) && diResource.isLoaded()) {
+ moveContents(sashResource, diResource);
+
+ if (sashResource.getContents().isEmpty()) {
+ // Schedule deletion on save
+ modelSet.getResourcesToDeleteOnSave().add(sashResource.getURI());
+ }
+ }
+ } else {
+ Resource sashResource;
+ URI privateURI = sashModel.getPrivateResourceURI();
+
+ // Move the contents into the sash model. If the sash resource isn't loaded
+ // or doesn't exist, it will have to be handled
+ if (modelSet.getURIConverter().exists(privateURI, null)) {
+ sashResource = modelSet.getResource(privateURI, true);
+ } else {
+ sashResource = modelSet.createResource(privateURI);
+ }
+
+ // In case we had marked it for deletion, earlier
+ modelSet.getResourcesToDeleteOnSave().remove(privateURI);
+
+ Resource diResource = toMove.eResource();
+ moveContents(diResource, sashResource);
+ }
+
+ // Re-load from the new resource. Snippets might find this odd, but
+ // it would be even more odd for there to be any snippets on this model
+ sashModel.loadModel(modelSet.getURIWithoutExtension());
+ }
+ };
+ }
+
+ return result;
+ }
+
+ void moveContents(Resource fromResource, Resource toResource) {
+ // Safe copy to allow concurrent modifications
+ for (EObject root : new ArrayList<>(fromResource.getContents())) {
+ EObject toReplace = (EObject) EcoreUtil.getObjectByType(toResource.getContents(), root.eClass());
+ if (toReplace != null) {
+ EcoreUtil.replace(toReplace, root);
+ } else {
+ if (root instanceof SashWindowsMngr) {
+ // This one is expected always to be first
+ toResource.getContents().add(0, root);
+ } else {
+ toResource.getContents().add(root);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Creates a command that toggles whether the sash model records the currently
+ * active page to restore it on next opening.
+ *
+ * @return a toggle command for the restore-active-page behaviour
+ */
+ public Command createToggleRestoreActivePageCommand() {
+ Command result = UnexecutableCommand.INSTANCE;
+
+ ModelSet modelSet = (ModelSet) editor.getAdapter(EditingDomain.class).getResourceSet();
+ SashWindowsMngr sashWindows = SashModelUtils.getSashWindowsMngr(modelSet);
+ ISashWindowsContainer container = editor.getAdapter(ISashWindowsContainer.class);
+
+ SashModel sashModel = sashWindows.getSashModel();
+ if (sashModel != null) {
+ // We don't record the tracking of the active page for undo/redo,
+ // so we cannot assume that any changes to the current page selections
+ // are undoable in the usual way
+ result = new AbstractToggleCommand("Toggle Restore Active Page") {
+
+ @Override
+ public void execute() {
+ boolean oldValue = sashModel.isRestoreActivePage();
+
+ if (oldValue) {
+ // Clear each tab folder's selection
+ container.getIFolderList().stream()
+ .map(f -> f.getRawModel())
+ .filter(TabFolder.class::isInstance).map(TabFolder.class::cast)
+ .filter(f -> f.getCurrentSelection() != null)
+ .forEach(f -> f.setCurrentSelection(null));
+ } else {
+ // Set each tab folder's selection.
+ // The 'visible pages' are the current selection in each folder
+ container.getVisiblePages().stream()
+ .map(p -> p.getRawModel())
+ .filter(PageRef.class::isInstance).map(PageRef.class::cast)
+ .filter(p -> p.getParent().getCurrentSelection() != p)
+ .forEach(p -> p.getParent().setCurrentSelection(p));
+ }
+
+ // The basic toggle
+ sashModel.setRestoreActivePage(!oldValue);
+ }
+ };
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ private static abstract class AbstractToggleCommand extends AbstractCommand {
+
+ AbstractToggleCommand(String label) {
+ super(label);
+ }
+
+ @Override
+ protected boolean prepare() {
+ // Nothing to prepare
+ return true;
+ }
+
+ @Override
+ public void undo() {
+ // It's a toggle, so yeah, just execute again
+ execute();
+ }
+
+ @Override
+ public void redo() {
+ execute();
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/TogglePageLayoutStorageHandler.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/TogglePageLayoutStorageHandler.java
new file mode 100644
index 00000000000..12fa47811e9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/commands/TogglePageLayoutStorageHandler.java
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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.ui.internal.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.utils.TransactionHelper;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.services.SaveLayoutBeforeClose;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * Command handler for the private page-layout storage toggle menu.
+ */
+public class TogglePageLayoutStorageHandler extends AbstractHandler {
+
+ public TogglePageLayoutStorageHandler() {
+ super();
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IEditorPart active = HandlerUtil.getActiveEditor(event);
+ if (active instanceof IMultiDiagramEditor) {
+ IMultiDiagramEditor editor = (IMultiDiagramEditor) active;
+
+ // Toggle the storage of the layout
+ togglePrivatePageLayout(editor);
+
+ // And then save the layout immediately if the editor is not dirty
+ // (if it is dirty, then the layout will be saved when the editor
+ // is saved; saving it now would possibly result in inconsistencies)
+ try {
+ SaveLayoutBeforeClose save = editor.getServicesRegistry().getService(SaveLayoutBeforeClose.class);
+ save.saveBeforeClose(editor);
+ } catch (ServiceException e) {
+ // Doesn't matter; we'll just have to rely on the normal editor save
+ }
+ }
+
+ return null;
+ }
+
+ public void togglePrivatePageLayout(IMultiDiagramEditor editor) {
+ Command command = new SashLayoutCommandFactory(editor).createTogglePrivateLayoutCommand();
+ EditingDomain domain = editor.getAdapter(EditingDomain.class);
+
+ // Don't execute on the undo history because the changes in the sash model
+ // are never tracked for undo/redo
+ try {
+ TransactionHelper.run(domain, () -> command.execute());
+ } catch (RollbackException e) {
+ StatusManager.getManager().handle(e.getStatus());
+ } catch (InterruptedException e) {
+ Activator.log.error("Failed to execute page layout toggle command", e); //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferencePage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferencePage.java
new file mode 100644
index 00000000000..bff4950d394
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferencePage.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2015, 2016 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.ui.internal.preferences;
+
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * The preference page for Papyrus Editor general preferences.
+ */
+public class EditorPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+
+ public EditorPreferencePage() {
+ super(Messages.EditorPreferencePage_0, SWT.FLAT);
+
+ setDescription(Messages.EditorPreferencePage_5);
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ setPreferenceStore(Activator.getDefault().getPreferenceStore());
+ }
+
+ @Override
+ protected void createFieldEditors() {
+ addField(new RadioGroupFieldEditor(EditorPreferences.PREF_CONVERT_SHARED_LAYOUT,
+ Messages.EditorPreferencePage_1,
+ 1,
+ new String[][] {
+ { Messages.EditorPreferencePage_2, YesNo.PROMPT.name() },
+ { Messages.EditorPreferencePage_3, YesNo.NO.name() },
+ { Messages.EditorPreferencePage_4, YesNo.YES.name() },
+ },
+ getFieldEditorParent()));
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferences.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferences.java
new file mode 100644
index 00000000000..0b8748f6032
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/EditorPreferences.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (c) 2015, 2016 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.ui.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.infra.ui.Activator;
+
+/**
+ * Accessor for the Papyrus Editor preferences.
+ */
+public class EditorPreferences {
+ public static final String PREF_CONVERT_SHARED_LAYOUT = "convertSharedLayout"; //$NON-NLS-1$
+
+ private static final EditorPreferences INSTANCE = new EditorPreferences();
+ private final IPreferenceStore store;
+
+ private EditorPreferences() {
+ super();
+
+ store = Activator.getDefault().getPreferenceStore();
+ }
+
+ public static EditorPreferences getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Queries whether the user prefers to migrate shared editor layout to private storage
+ * always, never, or interactively pop up a dialog to ask (the default).
+ *
+ * @return the shared layout conversion on first open preference, which is never
+ * {@code null} and defaults to {@link YesNo#PROMPT}
+ */
+ public YesNo getConvertSharedPageLayoutToPrivate() {
+ return YesNo.valueOf(store.getString(PREF_CONVERT_SHARED_LAYOUT));
+ }
+
+ /**
+ * Sets whether the editor will always, never, or ask the user to migrate shared
+ * (in the {@code *.di} resource) page layout into the private storage ({@code *.sash} resource}
+ * on the first opening of a Papyrus model in the workspace that uses the shared
+ * storage (usually from pre-1.0 release).
+ *
+ * @param convert
+ * the preference setting to assign, or {@code null} for the default, which
+ * is {@link YesNo#PROMPT}
+ */
+ public void setConvertSharedPageLayoutToPrivate(YesNo convert) {
+ if (convert == null) {
+ convert = YesNo.PROMPT;
+ }
+
+ store.setValue(PREF_CONVERT_SHARED_LAYOUT, convert.name());
+ }
+
+ //
+ // Nested types
+ //
+
+ /**
+ * Initializer of defaults for the editor preferences.
+ */
+ public static class Initializer extends AbstractPreferenceInitializer {
+
+ public Initializer() {
+ super();
+ }
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+
+ store.setDefault(PREF_CONVERT_SHARED_LAYOUT, YesNo.PROMPT.name());
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/Messages.java
new file mode 100644
index 00000000000..4fbebcf89bc
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/Messages.java
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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.ui.internal.preferences;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Translatable strings.
+ */
+class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.core.internal.preferences.messages"; //$NON-NLS-1$
+ public static String EditorPreferencePage_0;
+ public static String EditorPreferencePage_1;
+ public static String EditorPreferencePage_2;
+ public static String EditorPreferencePage_3;
+ public static String EditorPreferencePage_4;
+ public static String EditorPreferencePage_5;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/YesNo.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/YesNo.java
new file mode 100644
index 00000000000..a9ee87d9e4f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/YesNo.java
@@ -0,0 +1,21 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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.ui.internal.preferences;
+
+/**
+ * A tri-state boolean-ish preference data type with a "prompt the user" value.
+ */
+public enum YesNo {
+ PROMPT, NO, YES;
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/messages.properties
new file mode 100644
index 00000000000..a34a57ddfbe
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/internal/preferences/messages.properties
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2015 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
+#
+
+EditorPreferencePage_0=General Editor Settings
+EditorPreferencePage_1=Convert shared storage of editor layout to private:
+EditorPreferencePage_2=Ask each time
+EditorPreferencePage_3=Never
+EditorPreferencePage_4=Always
+EditorPreferencePage_5=General settings for the Papyrus multi-diagram editor.
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/DoSaveEvent.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/DoSaveEvent.java
new file mode 100644
index 00000000000..51e34e85d83
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/DoSaveEvent.java
@@ -0,0 +1,66 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+
+/**
+ * Event sent whith a Save or SaveAs.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class DoSaveEvent {
+
+ final protected ServicesRegistry serviceRegistry;
+
+ final protected IMultiDiagramEditor multiDiagramEditor;
+
+ final protected boolean isAutoSave;
+
+ /**
+ * Create an Event that is sent with a Save or SaveAs. The same event can be
+ * reused. Constructor.
+ *
+ * @param serviceRegistry
+ * @param multiDiagramEditor
+ */
+ public DoSaveEvent(ServicesRegistry serviceRegistry, IMultiDiagramEditor multiDiagramEditor) {
+ this(serviceRegistry, multiDiagramEditor, false);
+ }
+
+ /**
+ * Create an Event that is sent with a Save or SaveAs. The same event can be
+ * reused. Constructor.
+ *
+ * @param serviceRegistry
+ * @param multiDiagramEditor
+ * @param isAutoSave
+ */
+ public DoSaveEvent(ServicesRegistry serviceRegistry, IMultiDiagramEditor multiDiagramEditor, boolean isAutoSave) {
+ this.serviceRegistry = serviceRegistry;
+ this.multiDiagramEditor = multiDiagramEditor;
+ this.isAutoSave = isAutoSave;
+ }
+
+ /**
+ * @return the serviceRegistry
+ */
+ public ServicesRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ /**
+ * @return the multiDiagramEditor
+ */
+ public IMultiDiagramEditor getMultiDiagramEditor() {
+ return multiDiagramEditor;
+ }
+
+ public boolean isAutoSave() {
+ return isAutoSave;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/IEditorInputChangedListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/IEditorInputChangedListener.java
new file mode 100644
index 00000000000..64835143e55
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/IEditorInputChangedListener.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2010 LIFL & 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:
+ * Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Interface implemented by classes wishing to be notified of the inputChanged
+ * event after a call to {@link ISaveAndDirtyService#doSaveAs()}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface IEditorInputChangedListener {
+
+ /**
+ *
+ * @param fileEditorInput
+ * The new value of EditorInput
+ */
+ public void editorInputChanged(FileEditorInput fileEditorInput);
+
+ /**
+ * Called when the value of the isDirty() flag has changed.
+ */
+ public void isDirtyChanged();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ILifeCycleEventsProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ILifeCycleEventsProvider.java
new file mode 100644
index 00000000000..31f2afae670
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ILifeCycleEventsProvider.java
@@ -0,0 +1,57 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+/**
+ * Concrete implementation of this interface allows to listen on various
+ * lifecycle events. This interface is the "public" part of the {@link LifeCycleEventsProvider}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface ILifeCycleEventsProvider {
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addAboutToDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeAboutToDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addPostDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removePostDoSaveListener(ISaveEventListener listener);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveAndDirtyService.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveAndDirtyService.java
new file mode 100644
index 00000000000..a93b164ea0d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveAndDirtyService.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (c) 2010 LIFL & 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:
+ * Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.ISaveablePart;
+
+/**
+ * @author dumoulin
+ *
+ */
+public interface ISaveAndDirtyService extends ISaveablePart {
+
+ /**
+ * Register a nested {@link ISaveablePart} as a listener that will be
+ * notified each time a {@link #doSave(IProgressMonitor)} or {@link #doSaveAs()} is performed. Also, it will be asked for the
+ * dirtyState.
+ *
+ * @param saveablePart
+ */
+ public abstract void registerIsaveablePart(ISaveablePart saveablePart);
+
+ /**
+ * Remove the specified {@link ISaveablePart} from the list of listeners.
+ *
+ * @param saveablePart
+ */
+ public abstract void removeIsaveablePart(ISaveablePart saveablePart);
+
+ /**
+ * Add a listeners on input changed event.
+ *
+ * @param inputChangedListener
+ */
+ public void addInputChangedListener(IEditorInputChangedListener inputChangedListener);
+
+ /**
+ * Remove a listeners on input changed event.
+ *
+ * @param inputChangedListener
+ */
+ public void removeInputChangedListener(IEditorInputChangedListener inputChangedListener);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveEventListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveEventListener.java
new file mode 100644
index 00000000000..03d6aaa6a02
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/ISaveEventListener.java
@@ -0,0 +1,27 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+/**
+ * Interface used to listen on open, save and saveAs events.
+ *
+ * @author cedric dumoulin
+ *
+ * @param <T>
+ * Type of event passed to methods.
+ */
+public interface ISaveEventListener {
+
+ /**
+ *
+ * @param editor
+ */
+ public void doSave(DoSaveEvent event);
+
+ /**
+ *
+ * @param editor
+ */
+ public void doSaveAs(DoSaveEvent event);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProvider.java
new file mode 100644
index 00000000000..3fb4e594271
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProvider.java
@@ -0,0 +1,291 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides events about the life cycle of a MultiEditor. Not all
+ * life cycle events are available. Available events:
+ * <ul>
+ * <li>aboutToDoSave, aboutToDoSaveAs - SaveEventListener</li>
+ * <li>doSave, doSaveAs - SaveEventListener</li>
+ * <li>afterDoSave, afterDoSaveAs - SaveEventListener</li>
+ * <li></li>
+ * <li></li>
+ * </ul>
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class LifeCycleEventsProvider implements ILifeCycleEventsProvider {
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList preSaveListeners = new SaveEventListenerLazyList();
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList saveListeners = new SaveEventListenerLazyList();
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList postSaveListeners = new SaveEventListenerLazyList();
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void addDoSaveListener(ISaveEventListener listener) {
+
+ saveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void removeDoSaveListener(ISaveEventListener listener) {
+ saveListeners.removeListener(listener);
+ }
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void addAboutToDoSaveListener(ISaveEventListener listener) {
+
+ preSaveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void removeAboutToDoSaveListener(ISaveEventListener listener) {
+ preSaveListeners.removeListener(listener);
+ }
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void addPostDoSaveListener(ISaveEventListener listener) {
+
+ postSaveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ @Override
+ public void removePostDoSaveListener(ISaveEventListener listener) {
+ postSaveListeners.removeListener(listener);
+ }
+
+ // ****************************************************** //
+ // Fire events methods //
+ // ****************************************************** //
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireAboutToDoSaveEvent(DoSaveEvent event) {
+ preSaveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireAboutToDoSaveAsEvent(DoSaveEvent event) {
+ preSaveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireDoSaveEvent(DoSaveEvent event) {
+ saveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireDoSaveAsEvent(DoSaveEvent event) {
+ saveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void firePostDoSaveEvent(DoSaveEvent event) {
+ postSaveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void firePostDoSaveAsEvent(DoSaveEvent event) {
+ postSaveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire all Save events (about, events, post) to registered Listeners.
+ * Exceptions from listeners are propagated and stop the event chain.
+ *
+ * @param editorPart
+ */
+ public void fireAllDoSaveEvent(DoSaveEvent event) {
+ fireAboutToDoSaveEvent(event);
+ fireDoSaveEvent(event);
+ firePostDoSaveEvent(event);
+ }
+
+ /**
+ * Fire all SaveAs events (about, events, post) to registered Listeners. If
+ * one of the saveAs event fail, post events are not sent.
+ *
+ * @param editorPart
+ */
+ public void fireAllDoSaveAsEvent(DoSaveEvent event) {
+ fireAboutToDoSaveAsEvent(event);
+ fireDoSaveAsEvent(event);
+ firePostDoSaveAsEvent(event);
+ }
+
+ /**
+ * Base class encapsulating a lazy creation list.
+ *
+ * @author cedric dumoulin
+ *
+ * @param <T>
+ */
+ abstract protected class AbstractEventListenersLazyList<T> {
+
+ List<T> listeners;
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addListener(T listener) {
+ // Lazy creation
+ if (listeners == null) {
+ listeners = new ArrayList<T>();
+ }
+
+ // do not add if already present.
+ if (listeners.contains(listener)) {
+ return;
+ }
+
+ listeners.add(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeListener(T listener) {
+ // Lazy creation
+ if (listeners == null) {
+ return;
+ }
+
+ listeners.remove(listener);
+ }
+
+ /**
+ * @return the listeners
+ */
+ protected List<T> getListeners() {
+ return listeners;
+ }
+
+ /**
+ * Remove all listeners.
+ */
+ protected void clear() {
+ if (listeners != null) {
+ listeners.clear();
+ }
+ }
+ }
+
+ /**
+ * List of {@link ISaveEventListener}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+ protected class SaveEventListenerLazyList extends AbstractEventListenersLazyList<ISaveEventListener> {
+
+ /**
+ * Fire OpenEvent to registered Listeners. If a listener throw an
+ * exception, remaining listeners are called, and then the exception is
+ * resent.
+ *
+ * @param editorPart
+ */
+ public void fireSaveEvent(DoSaveEvent event) {
+ // Lazy creation
+ if (listeners == null) {
+ return;
+ }
+
+ for (ISaveEventListener listener : listeners) {
+ listener.doSave(event);
+ }
+ }
+
+ /**
+ * Fire OpenEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireSaveAsEvent(DoSaveEvent event) {
+ // Lazy creation
+ if (listeners == null) {
+ return;
+ }
+
+ for (ISaveEventListener listener : listeners) {
+ listener.doSaveAs(event);
+ }
+
+ }
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProviderServiceFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProviderServiceFactory.java
new file mode 100644
index 00000000000..b9126079262
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/LifeCycleEventsProviderServiceFactory.java
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * Copyright (c) 2010 LIFL & 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:
+ * Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import org.eclipse.papyrus.infra.core.services.IServiceFactory;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+
+/**
+ * A service factory to create the {@link ILifeCycleEventsProvider} service.
+ * This provide a nickname for {@link SaveAndDirtyService} service. This
+ * serviceFactory depends on {@link SaveAndDirtyService} service.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class LifeCycleEventsProviderServiceFactory implements IServiceFactory {
+
+ /**
+ * The sashModelMangr.
+ */
+ private SaveAndDirtyService saveAndDirtyService;
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ // Get required services
+ // This rely on the real implementation.
+ saveAndDirtyService = (SaveAndDirtyService) servicesRegistry.getService(ISaveAndDirtyService.class);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
+ *
+ * @return
+ * @throws ServiceException
+ */
+ @Override
+ public Object createServiceInstance() throws ServiceException {
+ return saveAndDirtyService;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/SaveAndDirtyService.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/SaveAndDirtyService.java
new file mode 100644
index 00000000000..7e858153695
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/lifecycleevents/SaveAndDirtyService.java
@@ -0,0 +1,550 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2013 LIFL & 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:
+ * Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - Don't make editor dirty on empty ResourceSetChangeEvent
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.lifecycleevents;
+
+import static org.eclipse.papyrus.infra.core.Activator.log;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListener;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * A Papyrus Service allowing to perform save and saveAs on Papyrus Models. The
+ * service also allows to listen on the dirty state of the Models. <br>
+ * The service implements the {@link ISaveablePart} interface, and can be used
+ * directly in part requiring such interface of adapter.
+ *
+ * <br>
+ * This class allows nested editors to register themselves as nested {@link ISaveablePart}. In this case, the registered part will be notified
+ * each time a save or saveAs is performed. Also, the nested part will be asked
+ * for its dirtyState.
+ *
+ * TODO : Improve the implementation by registering the isDirty flag value, and
+ * firing events only if the value really change. Actually, the event is fired
+ * every time the model is modified, even if the virtual value of the flag
+ * hasn't changed.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class SaveAndDirtyService extends LifeCycleEventsProvider implements ISaveablePart, IService, ISaveAndDirtyService {
+
+ /**
+ * Class used to propagate life cycle events. This class can be retrieved as
+ * a service using {@link ILifeCycleEventsProvider}.class. This class
+ * extends LifeCycleEventsProvider, so the local variable is set with
+ * ourself (historical reasons). TODO : remove this local variable.
+ */
+ protected LifeCycleEventsProvider lifeCycleEventsProvider = this;
+
+ /**
+ * Cached event that can be reused.
+ */
+ protected DoSaveEvent lifeCycleEvent;
+
+ /**
+ * Model set managing models.
+ */
+ private ModelSet resourceSet;
+
+ /**
+ *
+ */
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ /**
+ * The serviceRegistry.
+ */
+ // private ServicesRegistry servicesRegistry;
+
+ /**
+ * Associated editor. Needed by saveAs to synchronize editor input.
+ */
+ private IMultiDiagramEditor multiDiagramEditor;
+
+ /**
+ * List of registered {@link ISaveablePart}. This are usually nested
+ * editors.
+ */
+ private ISaveablePartList registeredIsaveablePart;
+
+ /**
+ * List of listeners on input changed event after a call to saveAs.
+ */
+ private List<IEditorInputChangedListener> inputChangedListeners;
+
+ /**
+ * Listener on commandStack changes.
+ */
+ private final CommandStackListener commandStackListener = new CommandStackListener() {
+
+ @Override
+ public void commandStackChanged(EventObject event) {
+
+ fireIsDirtyChanged();
+ };
+ };
+
+ /*
+ * Listener on ResourceSet
+ */
+ private final ResourceSetListener resourceSetListener = new ResourceSetListener() {
+
+ @Override
+ public NotificationFilter getFilter() {
+ return null;
+ }
+
+ @Override
+ public boolean isAggregatePrecommitListener() {
+ return false;
+ }
+
+ @Override
+ public boolean isPostcommitOnly() {
+ return true;
+ }
+
+ @Override
+ public boolean isPrecommitOnly() {
+ return false;
+ }
+
+ @Override
+ public void resourceSetChanged(ResourceSetChangeEvent event) {
+ if (event.getTransaction() != null && event.getTransaction().getStatus().isOK() && madePersistableChanges(event)) {
+ fireIsDirtyChanged();
+ }
+ }
+
+ private boolean madePersistableChanges(ResourceSetChangeEvent event) {
+ return !event.getNotifications().isEmpty() && !isUnprotected(event.getTransaction());
+ }
+
+ private boolean isUnprotected(Transaction transaction) {
+ return !Boolean.TRUE.equals(transaction.getOptions().get(Transaction.OPTION_UNPROTECTED));
+ }
+
+ @Override
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
+ return null;
+ }
+
+ };
+
+ /**
+ * Constructor.
+ *
+ */
+ public SaveAndDirtyService() {
+ registeredIsaveablePart = new ISaveablePartList();
+ inputChangedListeners = new ArrayList<IEditorInputChangedListener>();
+ }
+
+ /**
+ * Initialize the service. Retrieve other required services (ModelSet,
+ * CoreEditor).
+ *
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ * @throws ServiceException
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+
+ // this.servicesRegistry = servicesRegistry;
+
+ // Retrieve required services.
+ resourceSet = servicesRegistry.getService(ModelSet.class);
+ multiDiagramEditor = servicesRegistry.getService(IMultiDiagramEditor.class);
+ transactionalEditingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(servicesRegistry);
+
+ // Initialize and register the ILifeCycleEventsProvider service (which
+ // is ourself).
+ // This mean that the ILifeCycleEventsProvider is not available until we
+ // are started.
+ lifeCycleEvent = new DoSaveEvent(servicesRegistry, multiDiagramEditor);
+ // servicesRegistry.add(ILifeCycleEventsProvider.class, 1,
+ // lifeCycleEventsProvider);
+
+ }
+
+ /**
+ * Do nothing.
+ *
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void startService() throws ServiceException {
+
+ // Listen to the modifications of the EMF model
+ transactionalEditingDomain.getCommandStack().addCommandStackListener(commandStackListener);
+
+ // Let's listen to the resource set change
+ transactionalEditingDomain.addResourceSetListener(resourceSetListener);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
+ *
+ * @throws ServiceException
+ */
+ @Override
+ public void disposeService() throws ServiceException {
+ if (transactionalEditingDomain != null) {
+ // Check if commandStack is null (meaning that transactionalEditingDomain
+ // is disposed
+ CommandStack commandStack = transactionalEditingDomain.getCommandStack();
+ if (commandStack != null) {
+ transactionalEditingDomain.getCommandStack().removeCommandStackListener(commandStackListener);
+ }
+ transactionalEditingDomain.removeResourceSetListener(resourceSetListener);
+ // resourceSetListener = null;
+ }
+
+ // clean properties in order to help GC
+ inputChangedListeners.clear();
+ inputChangedListeners = null;
+ multiDiagramEditor = null;
+ // servicesRegistry = null;
+ transactionalEditingDomain = null;
+ resourceSet = null;
+ lifeCycleEvent = null;
+
+ postSaveListeners.clear();
+ saveListeners.clear();
+ preSaveListeners.clear();
+
+
+ }
+
+ /**
+ * Save the Models
+ *
+ * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ *
+ * @param monitor
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ // Sent pre doSave event
+ lifeCycleEventsProvider.fireAboutToDoSaveEvent(lifeCycleEvent);
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.fireDoSaveEvent(lifeCycleEvent);
+ // Perform local doSave
+ // TODO : put it in a listener ?
+ try {
+ // Save each associated resource
+ resourceSet.save(monitor);
+ // notify registered IsaveablePart
+ registeredIsaveablePart.doSave(monitor);
+ markSaveLocation();
+ } catch (IOException e) {
+ log.error("Error during save", e); //$NON-NLS-1$
+ }
+
+ // Sent post Events
+ lifeCycleEventsProvider.firePostDoSaveEvent(lifeCycleEvent);
+
+ }
+
+ /**
+ * @see org.eclipse.ui.ISaveablePart#doSaveAs()
+ *
+ */
+ @Override
+ public void doSaveAs() {
+ // Sent pre doSave event
+ lifeCycleEventsProvider.fireAboutToDoSaveAsEvent(lifeCycleEvent);
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.fireDoSaveAsEvent(lifeCycleEvent);
+ // Perform local doSaveAs
+
+ // Show a SaveAs dialog
+ Shell shell = multiDiagramEditor.getEditorSite().getWorkbenchWindow().getShell();
+ SaveAsDialog dialog = new SaveAsDialog(shell);
+ dialog.setOriginalFile(((IFileEditorInput) multiDiagramEditor.getEditorInput()).getFile());
+ dialog.open();
+ final IPath path = dialog.getResult();
+ if (path != null) {
+ // try to save the editor's contents under a different file name
+ final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ try {
+ new ProgressMonitorDialog(shell).run(false, // don't fork
+ false, // can't cancel
+ new WorkspaceModifyOperation() { // run this operation
+
+ @Override
+ public void execute(final IProgressMonitor monitor) {
+ try {
+ // to event bad redirection after the saveAs
+ // see bug 319023
+ EcoreUtil.resolveAll(resourceSet);
+ resourceSet.saveAs(path);
+ // notify registered IsaveablePart
+ registeredIsaveablePart.doSave(monitor);
+ } catch (IOException e) {
+ log.error("Unable to saveAs the resource set", e); //$NON-NLS-1$
+ }
+ }
+ });
+ // set input to the new file
+ fireEditorInputChanged(new FileEditorInput(file));
+ markSaveLocation();
+ } catch (InterruptedException e) {
+ // should not happen, since the monitor dialog is not cancelable
+ log.error(e);
+ } catch (InvocationTargetException e) {
+ log.error(e);
+ }
+ }
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.firePostDoSaveAsEvent(lifeCycleEvent);
+ }
+
+ /**
+ * Change the input of the underlying editor.
+ *
+ * @param fileEditorInput
+ */
+ private void fireEditorInputChanged(FileEditorInput fileEditorInput) {
+
+ for (IEditorInputChangedListener listener : inputChangedListeners) {
+ try {
+ listener.editorInputChanged(fileEditorInput);
+ } catch (Exception e) {
+ log.error("Can't set input for '" + listener + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+
+ /**
+ * Fire a PropertyChanged event to registered {@link IEditorInputChangedListener}.
+ *
+ * @param propertyId
+ */
+ private void fireIsDirtyChanged() {
+
+ for (IEditorInputChangedListener listener : inputChangedListeners) {
+ try {
+ listener.isDirtyChanged();
+ } catch (Exception e) {
+ log.error("Can't call listener '" + listener + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+
+ /**
+ * Return true if the multiEditor is dirty, false otherwise. The dirty state
+ * is compute as follow:
+ * <ul>
+ * <li>The {@link TransactionalEditingDomain} commandStack is checked</li>
+ * <li>and each registered nested Isaveable.isDirty() state is checked</li>
+ * <li></li>
+ * <li></li>
+ * <li></li>
+ * <li></li>
+ * </ul>
+ * If one of these states is false, the returned value is false. <br>
+ * If all of these states are true, the returned value is true.
+ *
+ * @see org.eclipse.ui.ISaveablePart#isDirty()
+ *
+ * @return
+ */
+ @Override
+ public boolean isDirty() {
+ // First, look if the model part (EMF) is dirty, else look at the
+ // Graphical part (GEF/GMF)
+ if (transactionalEditingDomain == null) {
+ return false;
+ }
+ return ((BasicCommandStack) transactionalEditingDomain.getCommandStack()).isSaveNeeded() || registeredIsaveablePart.isDirty();
+ }
+
+ /**
+ * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
+ *
+ * @return
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
+ *
+ * @return
+ */
+ @Override
+ public boolean isSaveOnCloseNeeded() {
+ return isDirty();
+ }
+
+ /**
+ * Mark the command stack of all sub-editors. Default implementation do
+ * nothing.
+ */
+ protected void markSaveLocation() {
+ ((BasicCommandStack) transactionalEditingDomain.getCommandStack()).saveIsDone();
+ fireIsDirtyChanged();
+ }
+
+ /**
+ * Register a nested {@link ISaveablePart} as a listener that will be
+ * notified each time a {@link #doSave(IProgressMonitor)} or {@link #doSaveAs()} is performed. Also, it will be asked for the
+ * dirtyState.
+ *
+ * @param saveablePart
+ */
+ @Override
+ public void registerIsaveablePart(ISaveablePart saveablePart) {
+ registeredIsaveablePart.add(saveablePart);
+ }
+
+ /**
+ * Remove the specified {@link ISaveablePart} from the list of listeners.
+ *
+ * @param saveablePart
+ */
+ @Override
+ public void removeIsaveablePart(ISaveablePart saveablePart) {
+ registeredIsaveablePart.remove(saveablePart);
+ }
+
+ /**
+ * Add a listeners on input changed event.
+ *
+ * @param inputChangedListener
+ */
+ @Override
+ public void addInputChangedListener(IEditorInputChangedListener inputChangedListener) {
+ inputChangedListeners.add(inputChangedListener);
+ }
+
+ /**
+ * Remove a listeners on input changed event.
+ *
+ * @param inputChangedListener
+ */
+ @Override
+ public void removeInputChangedListener(IEditorInputChangedListener inputChangedListener) {
+ inputChangedListeners.remove(inputChangedListener);
+ }
+
+ /**
+ * A list of {@link ISaveablePart}.
+ *
+ * @author dumoulin
+ *
+ */
+ public class ISaveablePartList extends ArrayList<ISaveablePart> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Return true if one of the part is dirty, false if all part are not
+ * dirty.
+ *
+ * @return
+ */
+ public boolean isDirty() {
+ for (ISaveablePart part : this) {
+ if (part.isDirty()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Call doSave on each registered {@link ISaveablePart}.
+ *
+ * @param monitor
+ */
+ public void doSave(IProgressMonitor monitor) {
+ for (ISaveablePart part : this) {
+
+ try {
+ part.doSave(monitor);
+ } catch (Exception e) {
+ log.error("Can't save ISaveablePart '" + part + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+
+ /**
+ * Call doSaveAs on each registered {@link ISaveablePart}.
+ *
+ * @param monitor
+ */
+ public void doSaveAs() {
+ for (ISaveablePart part : this) {
+ try {
+ part.doSaveAs();
+ } catch (Exception e) {
+ log.error("Can't save ISaveablePart '" + part + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractCommonCommandHandler.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractCommonCommandHandler.java
new file mode 100644
index 00000000000..deb6799a923
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractCommonCommandHandler.java
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * 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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.menu;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForHandlers;
+import org.eclipse.ui.ISources;
+
+/**
+ * This abstract command handler: - calculates the current selection -
+ * calculates the visibility and enablement based on command executability -
+ * executes the command in Papyrus command stack
+ *
+ */
+public abstract class AbstractCommonCommandHandler extends AbstractHandler {
+
+ /**
+ * Iterate over current selection and build a list of the {@link EObject} contained in the selection.
+ *
+ * @return the currently selected {@link EObject}
+ */
+ protected abstract List<EObject> getSelectedElements();
+
+ /**
+ *
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ *
+ * @param event
+ * @return null
+ * @throws ExecutionException
+ */
+ @Override
+ public abstract Object execute(ExecutionEvent event) throws ExecutionException;
+
+ protected TransactionalEditingDomain getEditingDomain(ExecutionEvent event) {
+ try {
+ return ServiceUtilsForHandlers.getInstance().getTransactionalEditingDomain(event);
+ } catch (ServiceException ex) {
+ return null;
+ }
+ }
+
+ @Override
+ public void setEnabled(Object evaluationContext) {
+ if (evaluationContext instanceof IEvaluationContext) {
+ Object selection = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+ if (selection instanceof Collection<?>) {
+ this.selection = (selection instanceof List<?>) ? (List<?>) selection : new java.util.ArrayList<Object>((Collection<?>) selection);
+ } else if (selection instanceof IStructuredSelection) {
+ this.selection = ((IStructuredSelection) selection).toList();
+ }
+ setBaseEnabled(computeEnabled());
+ this.selection = Collections.EMPTY_LIST;
+ }
+ super.setEnabled(evaluationContext);
+ }
+
+ protected boolean computeEnabled() {
+ List<EObject> elts = getSelectedElements();
+ return !(elts.size() == 0);
+ }
+
+ protected List<?> getSelection() {
+ return selection;
+ }
+
+ protected List<?> selection = Collections.EMPTY_LIST;
+
+ /**
+ *
+ * @return true if the command can be executed
+ */
+ public boolean isVisible() {
+ return isEnabled();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractEMFParametricOnSelectedElementsAction.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractEMFParametricOnSelectedElementsAction.java
new file mode 100644
index 00000000000..001b9b50bc4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractEMFParametricOnSelectedElementsAction.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * 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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.menu;
+
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.infra.ui.menu.AbstractParametricOnSelectedElementsAction;
+
+
+public abstract class AbstractEMFParametricOnSelectedElementsAction extends AbstractParametricOnSelectedElementsAction {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parameter
+ * parameter for the action
+ * @param selectedEditPart
+ * the selectedEditPart for the action
+ */
+ public AbstractEMFParametricOnSelectedElementsAction(String parameter, List<EObject> selectedEditPart) {
+ super(parameter, selectedEditPart);
+ }
+
+ /**
+ * Returns the command for this action
+ *
+ * @return
+ * the command for this action
+ */
+ public Command getCommand() {
+ if (isEnabled()) {
+ Command cmd = getBuildedCommand();
+ if (cmd != null && cmd.canExecute()) {
+ return cmd;
+ }
+ }
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ /**
+ *
+ * @return
+ * the command for this action
+ */
+ protected abstract Command getBuildedCommand();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractParametricOnSelectedElementsAction.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractParametricOnSelectedElementsAction.java
new file mode 100644
index 00000000000..5aa80a0b054
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/AbstractParametricOnSelectedElementsAction.java
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * 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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.menu;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers;
+
+
+public abstract class AbstractParametricOnSelectedElementsAction {
+
+ /**
+ * parameter for the action
+ */
+ protected String parameter;
+
+ /**
+ * selected EditPart
+ */
+ private List<EObject> selection;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parameter
+ * parameter for the action
+ * @param selectedEditPart
+ * the selectedEditPart for the action
+ */
+ public AbstractParametricOnSelectedElementsAction(String parameter, List<EObject> selectedEditPart) {
+ this.parameter = parameter;
+ this.selection = selectedEditPart;
+ }
+
+ /**
+ * Returns the selected Editparts for this action
+ *
+ * @return
+ * {@link #selection}
+ */
+ protected List<EObject> getSelection() {
+ return selection;
+ }
+
+ /**
+ * Test if the command can be build
+ *
+ * @return
+ * <code>true</code> if the command can be build
+ */
+ public boolean isEnabled() {
+ return true;
+ //return !selection.isEmpty();
+ }
+
+ /**
+ * Gets the parameter.
+ *
+ * @return the parameter
+ */
+ public String getParameter() {
+ return parameter;
+ }
+
+
+ /**
+ * Sets the parameter.
+ *
+ * @param parameter
+ * the new parameter
+ */
+ public void setParameter(String parameter) {
+ this.parameter = parameter;
+ }
+
+ /**
+ * executes the action
+ */
+ public void doRun(IProgressMonitor progressMonitor) {
+ // may be implemented by inherited class
+ };
+
+
+ /**
+ * Returns the {@link TransactionalEditingDomain}
+ *
+ * @return the {@link TransactionalEditingDomain} or <code>null</code> if it can not be found
+ */
+ protected TransactionalEditingDomain getEditingDomain() {
+ TransactionalEditingDomain editingDomain = null;
+ try {
+ editingDomain = ServiceUtilsForActionHandlers.getInstance().getTransactionalEditingDomain();
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return editingDomain;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalization.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalization.java
new file mode 100644
index 00000000000..44d3711682d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalization.java
@@ -0,0 +1,24 @@
+/*****************************************************************************
+ * 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.ui.menu;
+
+/**
+ * @author flefevre
+ *
+ */
+public interface NameNormalization {
+
+ public String normalizeName(String name, String parameter);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalizationCommand.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalizationCommand.java
new file mode 100644
index 00000000000..563cb346a83
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NameNormalizationCommand.java
@@ -0,0 +1,124 @@
+/*****************************************************************************
+ * 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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.menu;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+/**
+ * this command is used to create a link "satisfyBy" between requirement and namedElement
+ *
+ */
+public abstract class NameNormalizationCommand extends RecordingCommand implements NameNormalization{
+ protected EObject source;
+ protected String parameter;
+
+ private final String BLANK= new String("");//$NON-NLS-1$
+ private final String SPACE= new String(" ");//$NON-NLS-1$
+ private final String MULTISPACE= new String(" +");//$NON-NLS-1$
+ private final String UNDERSCORE= new String("_");//$NON-NLS-1$
+ private final String MULTIUNDERSCORE= new String("_+");//$NON-NLS-1$
+
+ public static final String NAME_ACTION="name quick formatting action";//$NON-NLS-1$
+
+ public static final String DEFAULT_ACTION="default";//$NON-NLS-1$
+ public static final String UPPERCASE_ACTION="uppercase";//$NON-NLS-1$
+ public static final String LOWERCASE_ACTION="lowercase";//$NON-NLS-1$
+ public static final String SWITCHSPACE2UNDERSCORE_ACTION="switchSpace2Underscore";//$NON-NLS-1$
+ public static final String CAPITALIZEFIRSTLETTER_ACTION="capitalizeFirstLetter";//$NON-NLS-1$
+ public static final String REMOVESPACE_ACTION="removeSpace";//$NON-NLS-1$
+
+ public NameNormalizationCommand(TransactionalEditingDomain domain, EObject source, String normalization){
+ super(domain,NAME_ACTION+": "+normalization);
+ this.source=source;
+ this.parameter=normalization;
+ }
+
+ public String normalizeName(String name, String parameter){
+ String newName = new String(name);
+ switch (parameter) {
+ case UPPERCASE_ACTION:
+ newName = getUpperCaseName(name);
+ break;
+ case LOWERCASE_ACTION:
+ newName = getLowerCaseName(name);
+ break;
+ case SWITCHSPACE2UNDERSCORE_ACTION:
+ newName = switchSpace2UnderscoreName(name);
+ break;
+ case REMOVESPACE_ACTION:
+ newName = removeSpaceName(name);
+ break;
+ case CAPITALIZEFIRSTLETTER_ACTION:
+ newName = capitalizeName(name);
+ break;
+
+ default:
+ newName = new String(name);
+ break;
+ }
+ return newName;
+ }
+
+ private String capitalizeName(String name) {
+ String[] ns = name.split(" ");
+ StringBuffer finalName=new StringBuffer();
+ for(String n : ns){
+ finalName.append(n.substring(0, 1).toUpperCase()+n.substring(1,n.length())+" ");
+ }
+ return finalName.toString().trim();
+ }
+
+ private String removeSpaceName(String name) {
+ StringBuffer finalName=new StringBuffer();
+ int spacePos = name.indexOf(SPACE);
+ if(spacePos>0){
+ finalName.append(name.replace(SPACE, BLANK));
+ }
+ else{
+ finalName.append(name.replaceAll("(.)([A-Z])", "$1 $2"));//$NON-NLS-1$
+ }
+
+ return finalName.toString().trim();
+ }
+
+ private String getUpperCaseName(String name){
+ return name.toUpperCase().trim();
+ }
+
+ private String getLowerCaseName(String name){
+ return name.toLowerCase().trim();
+ }
+
+ private String switchSpace2UnderscoreName(String name){
+ StringBuffer finalName=new StringBuffer();
+ int underscorePos = name.indexOf(UNDERSCORE);
+ int spacePos = name.indexOf(SPACE);
+ if(underscorePos>0 && spacePos>0 && underscorePos<spacePos){
+ finalName.append(name.replace(UNDERSCORE, BLANK));
+ }
+ else if(underscorePos>0 && spacePos>0 && underscorePos>spacePos){
+ finalName.append(name.replace(SPACE, UNDERSCORE));
+ }
+ else if(underscorePos<0 && spacePos>0 ){
+ finalName.append(name.replace(SPACE, UNDERSCORE));
+ }
+ else if(underscorePos>0 && spacePos<0){
+ finalName.append(name.replace(UNDERSCORE, SPACE));
+ }
+
+ return finalName.toString().trim().replaceAll(MULTISPACE, SPACE).replaceAll(MULTIUNDERSCORE, UNDERSCORE);
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NamePropertyTester.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NamePropertyTester.java
new file mode 100644
index 00000000000..70287ddb3a3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/menu/NamePropertyTester.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:
+ * Francois Le Fevre (CEA LIST) francois.le-fevre@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.menu;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+public abstract class NamePropertyTester extends PropertyTester {
+ /**
+ * property associated with the parameter linked to the command in the plugin.xml
+ */
+ public static final String PARAMETER_ID = new String("org.eclipse.papyrus.infra.ui.menu.quickformatcommandParameter"); //$NON-NLS-1$
+ /**
+ * property to test if a diagram has the required edit policy
+ */
+ public static final String IS_NAME_CHANGEABLE = "isNameChangeable"; //$NON-NLS-1$
+
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (IS_NAME_CHANGEABLE.equals(property) && receiver instanceof IStructuredSelection) {
+ boolean answer = isNameChangeable((IStructuredSelection) receiver);
+ return new Boolean(answer).equals(expectedValue);
+ }
+ return false;
+ }
+
+ protected abstract boolean isNameChangeable(IStructuredSelection selection);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/Messages.java
new file mode 100644
index 00000000000..4ece10f8d24
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/Messages.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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.messages;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.tools.messages.messages"; //$NON-NLS-1$
+
+ public static String AbstractPreferenceKeyDialog_Level;
+
+ public static String AbstractPreferenceKeyDialog_Localization;
+
+ public static String AbstractPreferenceKeyDialog_Pref_Kind;
+
+ public static String AbstractPreferenceKeyDialog_WouldYouLikeOverloadPreferences;
+
+ public static String AbstractStringValueConverter_NoXReprensentedByYHaveBeenFound;
+
+ public static String AbstractStringValueConverter_SomeStringsAreNotValidToCreateY;
+
+ public static String AbstractStringValueConverter_SomeStringsCantBeResolvedToFindY;
+
+ public static String AbstractStringValueConverter_TheFeatureXCantBeResolved;
+
+ public static String AbstractStringValueConverter_TheStringValueXCantBeResolved;
+
+ public static String AbstractStringValueConverter_TheStringXIsNotValidToCreateY;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/messages.properties
new file mode 100644
index 00000000000..845a45e10ab
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/messages/messages.properties
@@ -0,0 +1,10 @@
+AbstractPreferenceKeyDialog_Level=Level
+AbstractPreferenceKeyDialog_Localization=Localization
+AbstractPreferenceKeyDialog_Pref_Kind=Pref. kind
+AbstractPreferenceKeyDialog_WouldYouLikeOverloadPreferences=Would you like to overload those preferences?
+AbstractStringValueConverter_NoXReprensentedByYHaveBeenFound=No {0} represented by {1} have been found
+AbstractStringValueConverter_SomeStringsAreNotValidToCreateY=Some Strings are not valid to create {0}
+AbstractStringValueConverter_SomeStringsCantBeResolvedToFindY=Some Strings can't be resolved to find {0}
+AbstractStringValueConverter_TheFeatureXCantBeResolved=The feature {0} can't be resolved
+AbstractStringValueConverter_TheStringValueXCantBeResolved=The string value {0} can't be resolved
+AbstractStringValueConverter_TheStringXIsNotValidToCreateY=The String {0} is not valid to create {1}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java
new file mode 100644
index 00000000000..3af4448ed36
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor;
+
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * Descriptor of an ActionBarContributor. This descriptor is usually loaded from
+ * the Eclipse extension mechanism.
+ *
+ * @author Cedric Dumoulin
+ * @author Patrick Tessier
+ *
+ */
+public class ActionBarContributorDescriptor {
+
+ protected Class<? extends EditorActionBarContributor> contextClass;
+
+ protected String contextId;
+
+ /**
+ * Instance is created when requested.
+ */
+ protected EditorActionBarContributor instance = null;
+
+ /**
+ * constructor.
+ *
+ * @return the context descriptor
+ * @throws BackboneException
+ */
+ protected EditorActionBarContributor getActionBarContributor() throws BackboneException {
+ if (instance == null) {
+ instance = createActionBarContributor();
+ }
+
+ return instance;
+ }
+
+ private EditorActionBarContributor createActionBarContributor() throws BackboneException {
+ try {
+ EditorActionBarContributor context = contextClass.newInstance();
+ return context;
+
+ } catch (SecurityException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ }
+ }
+
+} // end class
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java
new file mode 100644
index 00000000000..da949ab92ae
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.infra.core.extension.BadNameExtensionException;
+import org.eclipse.papyrus.infra.core.extension.ExtensionException;
+import org.eclipse.papyrus.infra.core.extension.ExtensionUtils;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * A factory used to create ActionBarContributor object from Eclipse extensions
+ * points elements.
+ *
+ * @author Cedric Dumoulin
+ * @auhtor Patrick Tessier
+ */
+public class ActionBarContributorExtensionFactory extends ExtensionUtils {
+
+ /** singleton eINSTANCE of this class */
+ public final static ActionBarContributorExtensionFactory eINSTANCE = new ActionBarContributorExtensionFactory();
+
+ /** constant for the editor diagram **/
+ public final static String EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT = "" + "actionBarContributor";
+
+ /** constant for the attribute factoryClass **/
+ public final static String CONTEXTCLASS_ATTRIBUTE = "implementingClass";
+
+ /** constant for the attribute contextId **/
+ public final static String ID_ATTRIBUTE = "id";
+
+ /**
+ * @return the eINSTANCE
+ */
+ public static ActionBarContributorExtensionFactory getInstance() {
+ return eINSTANCE;
+ }
+
+ /**
+ * Create a ContextDescriptor instance corresponding to the
+ * ConfigurationElement.
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @return a ContextDescriptor structure that contains information to the
+ * diagram context
+ * @throws BadNameExtensionException
+ **/
+ public ActionBarContributorDescriptor createActionBarContributorDescriptor(IConfigurationElement element) throws ExtensionException {
+ ActionBarContributorDescriptor res;
+
+ checkTagName(element, EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT);
+
+ res = new ActionBarContributorDescriptor();
+ res.contextClass = (Class<EditorActionBarContributor>) parseClass(element, CONTEXTCLASS_ATTRIBUTE, EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT);
+ res.contextId = element.getAttribute(ID_ATTRIBUTE);
+
+ return res;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java
new file mode 100644
index 00000000000..347e1e0d5c7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java
@@ -0,0 +1,176 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor;
+
+import static org.eclipse.papyrus.infra.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.extension.ExtensionException;
+import org.eclipse.papyrus.infra.core.extension.NotFoundException;
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * A factory managing ActionBarContributor creation. The factory is loaded from
+ * ActionBarContributor declared in Eclipse extension mechanism.
+ *
+ * @author dumoulin
+ *
+ */
+public class ActionBarContributorRegistry implements IActionBarContributorFactory, IService {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusDiagram";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /**
+ * Registered context descriptors.
+ */
+ private Map<Object, ActionBarContributorDescriptor> editorContextDescriptors;
+
+ /**
+ * Constructor. defaultContext, input and site are explicitly required in
+ * order be sure that they are initialized. The multiEditor should be
+ * initialized. In particular, getEditorSite(), getEditorInput() and
+ * getDefaultContext() should return initialized values.
+ *
+ * @param multiEditor
+ * the multieditor
+ * @param extensionPointNamespace
+ */
+ public ActionBarContributorRegistry(String extensionPointNamespace) {
+
+ this.extensionPointNamespace = extensionPointNamespace;
+ initializeEditorContextDescriptors();
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public EditorActionBarContributor getActionBarContributor(Object key) throws BackboneException {
+ try {
+ ActionBarContributorDescriptor desc = editorContextDescriptors.get(key);
+ return desc.getActionBarContributor();
+ } catch (NullPointerException e) {
+ // no context found.
+ throw new NotFoundException("No ActionBarContributor registered under id '" + key + "'.");
+ }
+ }
+
+ /**
+ * Get the list of descriptors.
+ *
+ * @return
+ * @throws BackboneException
+ * If a contributor fail to be loaded.
+ */
+ public List<EditorActionBarContributor> getActionBarContributors() throws BackboneException {
+ List<EditorActionBarContributor> res = new ArrayList<EditorActionBarContributor>();
+ for (ActionBarContributorDescriptor desc : editorContextDescriptors.values()) {
+ res.add(desc.getActionBarContributor());
+ }
+ return res;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public void registerActionBarContributor(String contextKey, EditorActionBarContributor contributor) {
+ ActionBarContributorDescriptor desc = new ActionBarContributorDescriptor();
+ desc.contextId = contextKey;
+ desc.instance = contributor;
+ desc.contextClass = contributor.getClass();
+
+ editorContextDescriptors.put(contextKey, desc);
+ }
+
+ /**
+ * Read context descriptors from extension points.
+ */
+ private void initializeEditorContextDescriptors() {
+
+ editorContextDescriptors = new HashMap<Object, ActionBarContributorDescriptor>();
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+
+ ActionBarContributorExtensionFactory extensionReader = new ActionBarContributorExtensionFactory();
+
+ for (IConfigurationElement ele : configElements) {
+ ActionBarContributorDescriptor desc;
+ try {
+ if (ActionBarContributorExtensionFactory.EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT.equals(ele.getName())) {
+ desc = extensionReader.createActionBarContributorDescriptor(ele);
+ // Check double
+ if (editorContextDescriptors.get(desc.contextId) != null) {
+ // Already exists. Check if it is the same
+ ActionBarContributorDescriptor existingDesc = editorContextDescriptors.get(desc.contextId);
+ if (desc.equals(existingDesc)) {
+ log.warn("More than one ActionBarContributor is registered under the name '" + desc.contextId + "', with different parameters. Extra declaration are discarded.");
+ }
+ } else {
+ editorContextDescriptors.put(desc.contextId, desc);
+ }
+ }
+ } catch (ExtensionException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(this.getClass().getSimpleName() + " : contributors desc loaded [" + editorContextDescriptors.size() + "]");
+ }
+ }
+
+ /**
+ * Initialize the service. Do nothing here.
+ *
+ * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
+ *
+ * @param servicesRegistry
+ */
+ @Override
+ public void init(ServicesRegistry servicesRegistry) {
+
+ }
+
+ /**
+ * Do nothing in this implementation. {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.core.services.IService#startService()
+ */
+ @Override
+ public void startService() {
+ }
+
+ /**
+ * Do nothing in this implementation.
+ */
+ @Override
+ public void disposeService() {
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java
new file mode 100644
index 00000000000..2e8459fe5cf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright (c) 2008 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor;
+
+import java.util.List;
+
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.actionbarcontributor.ComposedActionBarContributor;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.actionbarcontributor.IMultiPageEditorActionBarContributor;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ *
+ * An ActionBarContributor composed of ActionBarContributor from multi editor.
+ * This ActionBarContributor switch to the contributor dedicated to the active
+ * editor in a MultiPageEditor environement.
+ *
+ * @author dumoulin
+ *
+ */
+public class CoreComposedActionBarContributor extends ComposedActionBarContributor implements IMultiPageEditorActionBarContributor {
+
+ /**
+ * The registry. Used to initialize the registered actionBars.
+ */
+ protected ActionBarContributorRegistry actionBarContributorRegistry;
+
+ protected List<EditorActionBarContributor> contributors;
+
+ /**
+ * Constructor.
+ *
+ * @throws BackboneException
+ */
+ public CoreComposedActionBarContributor() throws BackboneException {
+ // Init the contributors
+ loadContributors();
+ }
+
+ /**
+ *
+ * @throws BackboneException
+ */
+ private void loadContributors() throws BackboneException {
+ actionBarContributorRegistry = new ActionBarContributorRegistry(Activator.PLUGIN_ID);
+
+ contributors = actionBarContributorRegistry.getActionBarContributors();
+ }
+
+ /**
+ * @return the actionBarContributorRegistry
+ */
+ public ActionBarContributorRegistry getActionBarContributorRegistry() {
+ return actionBarContributorRegistry;
+ }
+
+ /**
+ * Dispose all nested ActionBarContributors.
+ */
+ @Override
+ public void dispose() {
+ // Dispose nested contributors.
+ for (EditorActionBarContributor contributor : contributors) {
+ contributor.dispose();
+ }
+ super.dispose();
+ }
+
+ /**
+ * Call the same method on each registered nested ActionBarContributors.
+ */
+ @Override
+ public void init(IActionBars bars, IWorkbenchPage page) {
+ super.init(bars, page);
+ buildActions();
+
+ // init nested contributors.
+ for (EditorActionBarContributor contributor : contributors) {
+ contributor.init(bars, page);
+ // remove GMF GlobalSaveAction from bar, fix bug 407854 - [Editor] The save action is disabled in Papyrus
+ bars.setGlobalActionHandler("save", null); // GMF is not using IWorkbenchCommandConstants.FILE_SAVE as ID //$NON-NLS-1$
+ }
+
+ }
+
+ /**
+ * Load default actions (undo/redo/delete)
+ *
+ * @see org.eclipse.gef.ui.actions.ActionBarContributor#buildActions()
+ */
+ protected void buildActions() {
+ // getActionBars().getToolBarManager().add(new UndoRetargetAction());
+ // getActionBars().getToolBarManager().add(new RedoRetargetAction());
+ }
+
+ @Override
+ public void setActiveEditor(IEditorPart part) {
+ super.setActiveEditor(part);
+ for (EditorActionBarContributor contributor : contributors) {
+ if (part != null) {
+ contributor.setActiveEditor(part);
+ }
+ }
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/IActionBarContributorFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/IActionBarContributorFactory.java
new file mode 100644
index 00000000000..e296d88deab
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/multidiagram/actionbarcontributor/IActionBarContributorFactory.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor;
+
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * Interface used to get an ActionBarContributor from its ID.
+ *
+ * @author dumoulin
+ *
+ */
+public interface IActionBarContributorFactory {
+
+ /**
+ * Get an ActionBarContributor by its key. If an ActionBarContributor
+ * already exists for this key, return it.
+ *
+ * @param key
+ * @return
+ */
+ public EditorActionBarContributor getActionBarContributor(Object key) throws BackboneException;
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferencePage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferencePage.java
new file mode 100644
index 00000000000..13426ddc474
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferencePage.java
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * Copyright (c) 2008, 2016 Atos Origin, 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:
+ * Thibault Landre (Atos Origin) - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.preferences;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+
+/**
+ * An abstract implementation of a Preference page.
+ *
+ * This preference page allows clients to define preference page in the preference of Eclipse, and
+ * in the properties of a project in the workspace.
+ * <p>
+ * Clients must implement :
+ * <ul>
+ * <li>{@link #getBundleId()} method in order to define the preference scope (Project or Instance) of the preference page.</li>
+ * <li>{@link #createPageContents(Composite)} method to populate the preference page with the different {@link AbstractPreferenceGroup}s. </br>
+ * Each group added has to be declared through the {@link #addPreferenceGroup(AbstractPreferenceGroup)}</code> method</li>
+ * </ul>
+ * </p>
+ */
+public abstract class AbstractPapyrusPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, IWorkbenchPropertyPage, IPapyrusPreferencePage {
+
+ private IProject project;
+
+ private Set<AbstractPreferenceGroup> groupSet;
+
+ private String key;
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
+ */
+ @Override
+ public IAdaptable getElement() {
+ return project;
+ }
+
+ protected void setPreferenceKey(String aKey) {
+ this.key = aKey;
+ }
+
+ protected String getPreferenceKey() {
+ return this.key;
+ }
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
+ */
+ @Override
+ public void setElement(IAdaptable element) {
+ project = (IProject) element.getAdapter(IResource.class);
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.PreferencePage#doGetPreferenceStore()
+ */
+ @Override
+ protected IPreferenceStore doGetPreferenceStore() {
+ IPreferenceStore store;
+ if (project != null) {
+ store = new ScopedPreferenceStore(new ProjectScope(project), getBundleId());
+ } else {
+ store = new ScopedPreferenceStore(InstanceScope.INSTANCE, getBundleId());
+ }
+ return store;
+ }
+
+ /**
+ * Initializes this preference page for the given workbench.
+ *
+ * @param workbench
+ * the workbench
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ *
+ */
+ @Override
+ public void init(IWorkbench workbench) {
+ // Do nothing
+ }
+
+ /**
+ * Create the Papyrus preference page and inits the different fields editor contained in the
+ * page.
+ * <p>
+ * This method shouldn't be overriden by sub-classes
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ // Create the container composite
+ Composite container = new Composite(parent, SWT.NONE);
+ GridLayout containerLayout = new GridLayout();
+ container.setLayout(containerLayout);
+
+ createPageContents(container);
+
+ initGroup();
+
+ return container;
+ }
+
+ /**
+ * Populate the preference page with the different field editor.
+ * <p>
+ * Each field added has to be declared through the <code>addEditorFields(FieldEditor fe)</code> method
+ * </p>
+ *
+ * @param parent
+ * the parent composite
+ */
+ protected abstract void createPageContents(Composite parent);
+
+ /**
+ * Add the given field editor to the page.
+ */
+ protected void addPreferenceGroup(AbstractPreferenceGroup fe) {
+ if (groupSet == null) {
+ groupSet = new HashSet<>();
+ }
+ groupSet.add(fe);
+ }
+
+ @Override
+ public boolean performOk() {
+ VisiblePageSingleton.getInstance().store();
+ return super.performOk();
+ }
+
+ /**
+ * Stores the values of the fields contained in this page into the preference store.
+ */
+ protected void storePreferences() {
+ if (groupSet != null) {
+ for (AbstractPreferenceGroup gs : groupSet) {
+ gs.storePreferences();
+ }
+ }
+ }
+
+ /**
+ * Store all preferences
+ */
+ @Override
+ public void storeAllPreferences() {
+ storePreferences();
+
+ }
+
+ @Override
+ protected void performDefaults() {
+ loadDefaultPreferences();
+ super.performDefaults();
+ }
+
+ /**
+ * Load the default preferences of the fields contained in this page
+ */
+ private void loadDefaultPreferences() {
+ if (groupSet != null) {
+ for (AbstractPreferenceGroup gs : groupSet) {
+ gs.loadDefault();
+ }
+ }
+
+ }
+
+ /**
+ * Init groups contained in this page.
+ */
+ private void initGroup() {
+ if (groupSet != null) {
+ for (AbstractPreferenceGroup gs : groupSet) {
+ gs.setPreferenceStore(getPreferenceStore());
+ gs.load();
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (groupSet != null) {
+ for (AbstractPreferenceGroup gs : groupSet) {
+ gs.dispose();
+ }
+ }
+
+
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible == true) {
+ VisiblePageSingleton.getInstance().setVisiblePage(this);
+ initGroup();
+ }
+ super.setVisible(visible);
+
+ }
+
+ /**
+ * The bundle ID used to defined the preference store
+ *
+ * @return String
+ */
+ protected abstract String getBundleId();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferenceStore.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferenceStore.java
new file mode 100644
index 00000000000..922fd74b9c3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPapyrusPreferenceStore.java
@@ -0,0 +1,300 @@
+/*****************************************************************************
+ * 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:
+ *
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.preferences.dialog.AbstractApplyValueOnPreferenceKeyDialog;
+
+public abstract class AbstractPapyrusPreferenceStore extends PapyrusScopedPreferenceStore {
+
+ /**
+ * key for element level
+ */
+ private final String elementLevelPrefix;
+
+ /**
+ * key for editor level
+ */
+ private final String instanceEditorLevelPrefix;
+
+ /**
+ * key for all editor of the same kind
+ */
+ private final String editorLevelPrefix;
+
+ /**
+ * constructor
+ *
+ * @param context
+ * the scope to store to
+ * @param qualifier
+ * the qualifier used to look up the preference node
+ * @param key
+ * for all editor of the same kind (all diagrams, all tables, ...)
+ * @param key
+ * for an instance of this editor
+ * @param key
+ * for an element
+ */
+ public AbstractPapyrusPreferenceStore(IScopeContext context, String qualifier, String editorLevelPrefix, String instanceEditorLevelPrefix, String elementLevelPrefix) {
+ super(context, qualifier);
+ this.editorLevelPrefix = editorLevelPrefix;
+ this.instanceEditorLevelPrefix = instanceEditorLevelPrefix;
+ this.elementLevelPrefix = elementLevelPrefix;
+ }
+
+ /**
+ * constructor
+ *
+ * @param context
+ * the scope to store to
+ * @param qualifier
+ * the qualifier used to look up the preference node
+ * @param defaultQualifierPath
+ * the qualifier used when looking up the defaults
+ * @param key
+ * for all editor of the same kind (all diagrams, all tables, ...)
+ * @param key
+ * for an instance of this editor
+ * @param key
+ * for an element
+ */
+ public AbstractPapyrusPreferenceStore(IScopeContext context, String qualifier, String defaultQualifierPath, String editorLevelPrefix, String instanceEditorLevelPrefix, String elementLevelPrefix) {
+ super(context, qualifier, defaultQualifierPath);
+ this.editorLevelPrefix = editorLevelPrefix;
+ this.instanceEditorLevelPrefix = instanceEditorLevelPrefix;
+ this.elementLevelPrefix = elementLevelPrefix;
+ }
+
+
+
+
+ /**
+ * this method is used to overload all value under a level of preferences.
+ * In order to overload a pop-up is opened, and the user can choose value to overload
+ *
+ * @param level
+ * of preference: Editor or diagram
+ */
+
+ public void deleteAllSubPreference(String level) {
+ // remove all sub value diagram+ element
+
+ // key to collect
+ List<String> elementKey = new ArrayList<String>();
+ try {
+ for (int i = 0; i < getStorePreferences().keys().length; i++) {
+ // level diagram collect only element
+ if (level.startsWith(instanceEditorLevelPrefix)) {
+ if (getStorePreferences().keys()[i].startsWith(elementLevelPrefix)) {
+ elementKey.add(getStorePreferences().keys()[i]);
+ }
+ }
+ // editor level, collect all element+diagram
+ else if (level.startsWith(editorLevelPrefix)) {
+ if ((getStorePreferences().keys()[i].startsWith(elementLevelPrefix)) || (getStorePreferences().keys()[i].startsWith(instanceEditorLevelPrefix))) {
+ elementKey.add(getStorePreferences().keys()[i]);
+ }
+ }
+
+ }
+
+ } catch (Exception e) {
+ Activator.log.error(e);
+ }
+ if (elementKey.size() > 0) {
+ List<String> keytoRemove = new ArrayList<String>();
+ String[] keyRoconsult = new String[elementKey.size()];
+ AbstractApplyValueOnPreferenceKeyDialog dialog = createPreferenceKeyDialog(elementKey.toArray(keyRoconsult));
+ dialog.open();
+ keytoRemove = dialog.getKeyToRemove();
+
+ // remove key
+ Iterator<String> iterator = keytoRemove.iterator();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ getStorePreferences().remove(key);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param keys
+ * @return
+ * the dialog to apply values
+ */
+ protected abstract AbstractApplyValueOnPreferenceKeyDialog createPreferenceKeyDialog(String[] keys);
+
+
+
+ // each get value will be overloaded
+ // if not value is found for an element, a value is look for in DIAGRAM
+ // if a the value is not find for Diagram a value is find for Papyrus editor
+
+
+ /**
+ * this method is used to find a key that a got a value:
+ * if the key is an element. The method look for if this key exist. If no value exists, it look for the key for diagram
+ * if the key for diagram do not exist it look for key for papyrus Editor
+ * the structure of Key is:
+ * element : ELEMENT_DiagramKind_ElementKind.preferenceKind
+ * Diagram : DIAGRAM_DiagramKind.preferenceKind
+ * Editor: PAPYRUS_EDITOR.preferenceKind
+ *
+ */
+ protected String findKeyWithAValue(String initialKey) {
+ String foundedKey = null;
+ // first look for in value stack
+ foundedKey = findKeyAStoreValue(initialKey);
+ // then look for in default stack
+ if (foundedKey == null) {
+ foundedKey = findKeyWithADefaultValue(initialKey);
+ }
+ if (foundedKey == null) {
+ foundedKey = initialKey;
+ }
+ return foundedKey;
+
+ }
+
+ /**
+ * look for a key with a value in the store stack
+ *
+ * @param initialKey
+ * element : ELEMENT_DiagramKind_ElementKind.preferenceKind
+ * Diagram : DIAGRAM_DiagramKind.preferenceKind
+ * Editor: PAPYRUS_EDITOR.preferenceKind
+ * @return the key that returns a value or null if there is no value
+ */
+ protected String findKeyAStoreValue(String initialKey) {
+ String foundedKey = null;
+ if (getStorePreferences().get(initialKey, null) != null) {
+ foundedKey = initialKey;
+ }
+
+ if (foundedKey == null && hasPrefix(initialKey)) {
+ foundedKey = findKeyAStoreValue(getUpperKey(initialKey));
+ }
+ return foundedKey;
+ }
+
+ /**
+ * this method is used to find a key that a got a value:
+ * if the key is an element. The method look for if this key exist. If no value exists, it look for the key for diagram
+ * if the key for diagram do not exist it look for key for papyrus Editor
+ * the structure of Key is:
+ * element : ELEMENT_DiagramKind_ElementKind.preferenceKind
+ * Diagram : DIAGRAM_DiagramKind.preferenceKind
+ * Editor: PAPYRUS_EDITOR.preferenceKind
+ *
+ */
+ protected String findKeyWithADefaultValue(String initialKey) {
+ String foundedKey = null;
+
+ if (getDefaultPreferences().get(initialKey, null) != null) {
+ foundedKey = initialKey;
+ }
+
+ if (foundedKey == null && hasPrefix(initialKey)) {
+ return findKeyWithADefaultValue(getUpperKey(initialKey));
+ } else {
+ foundedKey = initialKey;
+ }
+ return foundedKey;
+
+ }
+
+ /**
+ * get the upper Key from the initial Key
+ * * the structure of Key is:
+ * element : ELEMENT_DiagramKind_ElementKind.preferenceKind
+ * Diagram : DIAGRAM_DiagramKind.preferenceKind
+ * Editor: PAPYRUS_EDITOR.preferenceKind
+ *
+ * @param initialKey
+ * @return the upperKey
+ *
+ */
+ protected String getUpperKey(String initialKey) {
+
+ String out = initialKey.toString();
+ if (initialKey.startsWith(elementLevelPrefix)) {
+ out = initialKey.toString().replaceAll(elementLevelPrefix, instanceEditorLevelPrefix);
+ out = out.substring(0, out.lastIndexOf("_")) + out.substring(out.indexOf("."), out.length());
+ }
+ if (initialKey.startsWith(instanceEditorLevelPrefix)) {
+ // out=initialKey.toString().replaceAll(instanceEditorLevelPrefix, editorLevelPrefix);
+ out = editorLevelPrefix + out.substring(out.indexOf("."), out.length());
+ }
+ return out;
+ }
+
+ protected boolean hasPrefix(String key) {
+ if (key.startsWith(elementLevelPrefix) || key.startsWith(instanceEditorLevelPrefix)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * get the value from a key
+ *
+ * @param key
+ * @return the value
+ */
+ @Override
+ protected String internalGet(String key) {
+ String newKey = findKeyWithAValue(key);
+ // System.err.println("-->Initial Key "+key+"--> "+ newKey);
+ return Platform.getPreferencesService().get(newKey, null, getPreferenceNodes(true));
+ }
+
+ @Override
+ public boolean getDefaultBoolean(String name) {
+
+ return super.getDefaultBoolean(findKeyWithADefaultValue(name));
+ }
+
+ @Override
+ public double getDefaultDouble(String name) {
+ return super.getDefaultDouble(findKeyWithADefaultValue(name));
+ }
+
+ @Override
+ public float getDefaultFloat(String name) {
+ return super.getDefaultFloat(findKeyWithADefaultValue(name));
+ };
+
+ @Override
+ public int getDefaultInt(String name) {
+ return super.getDefaultInt(findKeyWithADefaultValue(name));
+ }
+
+ @Override
+ public long getDefaultLong(String name) {
+ return super.getDefaultLong(findKeyWithADefaultValue(name));
+ }
+
+ @Override
+ public String getDefaultString(String name) {
+ return super.getDefaultString(findKeyWithADefaultValue(name));
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPreferenceGroup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPreferenceGroup.java
new file mode 100644
index 00000000000..b90d098e54b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/AbstractPreferenceGroup.java
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * Copyright (c) 2009, 2016 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:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr
+ * Thibault Landre (Atos Origin)
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.preferences;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.preference.FieldEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The Class AbstractPreferenceGroup.
+ */
+public abstract class AbstractPreferenceGroup extends Composite {
+
+ /** The key to find preference */
+ private String key;
+
+ /**
+ * The fieldsEditor : a set that will contain all editor in the composite. It is in charge of
+ * loading / storing / setting the preference store / loading default of all its contained field
+ * editor
+ */
+ private Set<FieldEditor> fieldsEditor;
+
+ /**
+ * Gets the dialog page.
+ *
+ * @return the dialogPage
+ */
+ protected DialogPage getDialogPage() {
+ return dialogPage;
+ }
+
+ /** The dialog page. */
+ protected DialogPage dialogPage;
+
+ /**
+ * Gets the title.
+ *
+ * @return the title
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Sets the title.
+ *
+ * @param title
+ * the title to set
+ */
+ protected void setKey(String title) {
+ this.key = title;
+ }
+
+ /**
+ * Instantiates a new abstract group.
+ *
+ * @param parent
+ * the parent of the composite
+ * @param String
+ * the title of the page
+ * @param dialogPage
+ * to set the page in field editor
+ */
+ public AbstractPreferenceGroup(Composite parent, String key, DialogPage dialogPage) {
+ super(parent, SWT.None);
+ this.key = key;
+ this.dialogPage = dialogPage;
+ this.setLayout(new GridLayout());
+ fieldsEditor = new HashSet<FieldEditor>();
+ }
+
+ /**
+ * Gets an encapsulated composite. This composite is used to contain a FieldEditor and to allow
+ * developers to work with a FieldEditor like Composite element.
+ *
+ * @param parent
+ * the parent
+ *
+ * @return the encapsulated compo
+ */
+ protected final Composite getEncapsulatedComposite(Composite parent) {
+ Composite compo = new Composite(parent, SWT.NONE);
+ compo.setLayout(new GridLayout());
+ return compo;
+ }
+
+ /**
+ * Register field editor. It will add the fieldEditor to a map that will be used to
+ * store/load/loadDefault/set the PreferenceStore of contained fieldEditor
+ *
+ * @param fieldEditor
+ * the fieldEditor to add.
+ */
+ protected void addFieldEditor(FieldEditor fieldEditor) {
+ fieldsEditor.add(fieldEditor);
+ }
+
+ /**
+ * Load preferences of all registered fieldEditors.
+ *
+ * @see org.eclipse.papyrus.infra.AbstractPreferenceGroup.preferences.ui.AbstractGroup#addFieldEditor(FieldEditor)
+ */
+ public void load() {
+ for (FieldEditor fe : fieldsEditor) {
+ fe.load();
+ }
+ }
+
+ /**
+ * Set the preference store of all registered fieldEditors.
+ *
+ * @see org.eclipse.papyrus.infra.AbstractPreferenceGroup.preferences.ui.AbstractGroup#addFieldEditor(FieldEditor)
+ */
+ public final void setPreferenceStore(IPreferenceStore store) {
+ for (FieldEditor fe : fieldsEditor) {
+ fe.setPreferenceStore(store);
+ }
+ }
+
+ /**
+ * Load default preferences of all registered fieldEditors.
+ *
+ * @see org.eclipse.papyrus.infra.AbstractPreferenceGroup.preferences.ui.AbstractGroup#addFieldEditor(FieldEditor)
+ */
+ public final void loadDefault() {
+ for (FieldEditor fe : fieldsEditor) {
+ fe.loadDefault();
+ }
+ }
+
+ /**
+ * Store preferences of the registered fieldEditors.
+ *
+ * @see org.eclipse.papyrus.infra.AbstractPreferenceGroup.preferences.ui.AbstractGroup#addFieldEditor(FieldEditor)
+ */
+ public final void storePreferences() {
+ for (FieldEditor fe : fieldsEditor) {
+ fe.store();
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/IPapyrusPreferencePage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/IPapyrusPreferencePage.java
new file mode 100644
index 00000000000..4a82d671fef
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/IPapyrusPreferencePage.java
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 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 485220
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferencePage;
+
+/**
+ * Specialized protocol for preference pages participating in the {@link VisiblePageSingleton}
+ * mechanism.
+ */
+public interface IPapyrusPreferencePage extends IPreferencePage {
+ /**
+ * Requests the page to store all of its preferences in the preference store.
+ */
+ void storeAllPreferences();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/PapyrusScopedPreferenceStore.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/PapyrusScopedPreferenceStore.java
new file mode 100644
index 00000000000..f3ec34c88c1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/PapyrusScopedPreferenceStore.java
@@ -0,0 +1,858 @@
+/*****************************************************************************
+ * 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.ui.preferences;
+
+/***************************************************************************
+ 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:
+ * the code is copy from ScopedPreferenceStore but I have open some methods in order to be
+ * available for the overload
+ *
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *
+ *
+ *******************************************************************************/
+
+import java.io.IOException;
+
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.jface.preference.IPersistentPreferenceStore;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.ui.internal.WorkbenchMessages;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes
+ * provided in org.eclipse.core.runtime.preferences.
+ * <p>
+ * A ScopedPreferenceStore does the lookup of a preference based on it's search scopes and sets the value of the preference based on its store scope.
+ * </p>
+ * <p>
+ * The default scope is always included in the search scopes when searching for preference values.
+ * </p>
+ *
+ * @see org.eclipse.core.runtime.preferences
+ * @since 3.1
+ */
+public class PapyrusScopedPreferenceStore extends EventManager implements IPreferenceStore, IPersistentPreferenceStore {
+
+ /**
+ * The storeContext is the context where values will stored with the
+ * setValue methods. If there are no searchContexts this will be the search
+ * context. (along with the "default" context)
+ */
+ protected IScopeContext storeContext;
+
+ /**
+ * The searchContext is the array of contexts that will be used by the get
+ * methods for searching for values.
+ */
+ protected IScopeContext[] searchContexts;
+
+ /**
+ * A boolean to indicate the property changes should not be propagated.
+ */
+ protected boolean silentRunning = false;
+
+ /**
+ * The listener on the IEclipsePreferences. This is used to forward updates
+ * to the property change listeners on the preference store.
+ */
+ protected IEclipsePreferences.IPreferenceChangeListener preferencesListener;
+
+ /**
+ * The default context is the context where getDefault and setDefault
+ * methods will search. This context is also used in the search.
+ */
+ protected IScopeContext defaultContext = DefaultScope.INSTANCE;
+
+ /**
+ * The nodeQualifer is the string used to look up the node in the contexts.
+ */
+ protected String nodeQualifier;
+
+ /**
+ * The defaultQualifier is the string used to look up the default node.
+ */
+ protected String defaultQualifier;
+
+ /**
+ * Boolean value indicating whether or not this store has changes to be
+ * saved.
+ */
+ private boolean dirty;
+
+ /**
+ * Create a new instance of the receiver. Store the values in context in the
+ * node looked up by qualifier. <strong>NOTE:</strong> Any instance of
+ * ScopedPreferenceStore should call
+ *
+ * @param context
+ * the scope to store to
+ * @param qualifier
+ * the qualifier used to look up the preference node
+ * @param defaultQualifierPath
+ * the qualifier used when looking up the defaults
+ */
+ public PapyrusScopedPreferenceStore(IScopeContext context, String qualifier, String defaultQualifierPath) {
+ this(context, qualifier);
+ this.defaultQualifier = defaultQualifierPath;
+ }
+
+ /**
+ * Create a new instance of the receiver. Store the values in context in the
+ * node looked up by qualifier.
+ *
+ * @param context
+ * the scope to store to
+ * @param qualifier
+ * the qualifer used to look up the preference node
+ */
+ public PapyrusScopedPreferenceStore(IScopeContext context, String qualifier) {
+ storeContext = context;
+ this.nodeQualifier = qualifier;
+ this.defaultQualifier = qualifier;
+
+ ((IEclipsePreferences) getStorePreferences().parent()).addNodeChangeListener(getNodeChangeListener());
+ }
+
+ /**
+ * Return a node change listener that adds a removes the receiver when nodes
+ * change.
+ *
+ * @return INodeChangeListener
+ */
+ private INodeChangeListener getNodeChangeListener() {
+ return new IEclipsePreferences.INodeChangeListener() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#added(org.eclipse.core.runtime.preferences.IEclipsePreferences
+ * .NodeChangeEvent)
+ */
+ public void added(NodeChangeEvent event) {
+ if (nodeQualifier.equals(event.getChild().name()) && isListenerAttached()) {
+ getStorePreferences().addPreferenceChangeListener(preferencesListener);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.
+ * IEclipsePreferences.NodeChangeEvent)
+ */
+ public void removed(NodeChangeEvent event) {
+ // Do nothing as there are no events from removed node
+ }
+ };
+ }
+
+ /**
+ * Initialize the preferences listener.
+ */
+ private void initializePreferencesListener() {
+ if (preferencesListener == null) {
+ preferencesListener = new IEclipsePreferences.IPreferenceChangeListener() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.
+ * preferences.IEclipsePreferences.PreferenceChangeEvent)
+ */
+ public void preferenceChange(PreferenceChangeEvent event) {
+
+ if (silentRunning) {
+ return;
+ }
+
+ Object oldValue = event.getOldValue();
+ Object newValue = event.getNewValue();
+ String key = event.getKey();
+ if (newValue == null) {
+ newValue = getDefault(key, oldValue);
+ } else if (oldValue == null) {
+ oldValue = getDefault(key, newValue);
+ }
+ firePropertyChangeEvent(event.getKey(), oldValue, newValue);
+ }
+ };
+ getStorePreferences().addPreferenceChangeListener(preferencesListener);
+ }
+
+ }
+
+ /**
+ * Does its best at determining the default value for the given key. Checks
+ * the given object's type and then looks in the list of defaults to see if
+ * a value exists. If not or if there is a problem converting the value, the
+ * default default value for that type is returned.
+ *
+ * @param key
+ * the key to search
+ * @param obj
+ * the object who default we are looking for
+ * @return Object or <code>null</code>
+ */
+ protected Object getDefault(String key, Object obj) {
+ IEclipsePreferences defaults = getDefaultPreferences();
+ if (obj instanceof String) {
+ return defaults.get(key, STRING_DEFAULT_DEFAULT);
+ } else if (obj instanceof Integer) {
+ return Integer.valueOf(defaults.getInt(key, INT_DEFAULT_DEFAULT));
+ } else if (obj instanceof Double) {
+ return new Double(defaults.getDouble(key, DOUBLE_DEFAULT_DEFAULT));
+ } else if (obj instanceof Float) {
+ return new Float(defaults.getFloat(key, FLOAT_DEFAULT_DEFAULT));
+ } else if (obj instanceof Long) {
+ return Long.valueOf(defaults.getLong(key, LONG_DEFAULT_DEFAULT));
+ } else if (obj instanceof Boolean) {
+ return defaults.getBoolean(key, BOOLEAN_DEFAULT_DEFAULT) ? Boolean.TRUE : Boolean.FALSE;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return the IEclipsePreferences node associated with this store.
+ *
+ * @return the preference node for this store
+ */
+ protected IEclipsePreferences getStorePreferences() {
+ return storeContext.getNode(nodeQualifier);
+ }
+
+ /**
+ * Return the default IEclipsePreferences for this store.
+ *
+ * @return this store's default preference node
+ */
+ protected IEclipsePreferences getDefaultPreferences() {
+ return defaultContext.getNode(defaultQualifier);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ initializePreferencesListener();// Create the preferences listener if it
+ // does not exist
+ addListenerObject(listener);
+ }
+
+ /**
+ * Return the preference path to search preferences on. This is the list of
+ * preference nodes based on the scope contexts for this store. If there are
+ * no search contexts set, then return this store's context.
+ * <p>
+ * Whether or not the default context should be included in the resulting list is specified by the <code>includeDefault</code> parameter.
+ * </p>
+ *
+ * @param includeDefault
+ * <code>true</code> if the default context should be included
+ * and <code>false</code> otherwise
+ * @return IEclipsePreferences[]
+ * @since 3.4 public, was added in 3.1 as private method
+ */
+ public IEclipsePreferences[] getPreferenceNodes(boolean includeDefault) {
+ // if the user didn't specify a search order, then return the scope that
+ // this store was created on. (and optionally the default)
+ if (searchContexts == null) {
+ if (includeDefault) {
+ return new IEclipsePreferences[] { getStorePreferences(), getDefaultPreferences() };
+ }
+ return new IEclipsePreferences[] { getStorePreferences() };
+ }
+ // otherwise the user specified a search order so return the appropriate
+ // nodes based on it
+ int length = searchContexts.length;
+ if (includeDefault) {
+ length++;
+ }
+ IEclipsePreferences[] preferences = new IEclipsePreferences[length];
+ for (int i = 0; i < searchContexts.length; i++) {
+ preferences[i] = searchContexts[i].getNode(nodeQualifier);
+ }
+ if (includeDefault) {
+ preferences[length - 1] = getDefaultPreferences();
+ }
+ return preferences;
+ }
+
+ /**
+ * Set the search contexts to scopes. When searching for a value the seach
+ * will be done in the order of scope contexts and will not search the
+ * storeContext unless it is in this list.
+ * <p>
+ * If the given list is <code>null</code>, then clear this store's search contexts. This means that only this store's scope context and default scope will be used during preference value searching.
+ * </p>
+ * <p>
+ * The defaultContext will be added to the end of this list automatically and <em>MUST NOT</em> be included by the user.
+ * </p>
+ *
+ * @param scopes
+ * a list of scope contexts to use when searching, or <code>null</code>
+ */
+ public void setSearchContexts(IScopeContext[] scopes) {
+ this.searchContexts = scopes;
+ if (scopes == null) {
+ return;
+ }
+
+ // Assert that the default was not included (we automatically add it to
+ // the end)
+ for (int i = 0; i < scopes.length; i++) {
+ if (scopes[i].equals(defaultContext)) {
+ Assert.isTrue(false, WorkbenchMessages.ScopedPreferenceStore_DefaultAddedError);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#contains(java.lang.String)
+ */
+ public boolean contains(String name) {
+ if (name == null) {
+ return false;
+ }
+ return (Platform.getPreferencesService().get(name, null, getPreferenceNodes(true))) != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#firePropertyChangeEvent(java.lang.String,
+ * java.lang.Object, java.lang.Object)
+ */
+ public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
+ // important: create intermediate array to protect against listeners
+ // being added/removed during the notification
+ final Object[] list = getListeners();
+ if (list.length == 0) {
+ return;
+ }
+ final PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
+ for (int i = 0; i < list.length; i++) {
+ final IPropertyChangeListener listener = (IPropertyChangeListener) list[i];
+ SafeRunner.run(new SafeRunnable(JFaceResources.getString("PreferenceStore.changeError")) { //$NON-NLS-1$
+
+ public void run() {
+ listener.propertyChange(event);
+ }
+ });
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getBoolean(java.lang.String)
+ */
+ public boolean getBoolean(String name) {
+ String value = internalGet(name);
+ return value == null ? BOOLEAN_DEFAULT_DEFAULT : Boolean.valueOf(value).booleanValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultBoolean(java.lang.String)
+ */
+ public boolean getDefaultBoolean(String name) {
+ return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultDouble(java.lang.String)
+ */
+ public double getDefaultDouble(String name) {
+ return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultFloat(java.lang.String)
+ */
+ public float getDefaultFloat(String name) {
+ return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultInt(java.lang.String)
+ */
+ public int getDefaultInt(String name) {
+ return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultLong(java.lang.String)
+ */
+ public long getDefaultLong(String name) {
+ return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultString(java.lang.String)
+ */
+ public String getDefaultString(String name) {
+ return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getDouble(java.lang.String)
+ */
+ public double getDouble(String name) {
+ String value = internalGet(name);
+ if (value == null) {
+ return DOUBLE_DEFAULT_DEFAULT;
+ }
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ return DOUBLE_DEFAULT_DEFAULT;
+ }
+ }
+
+ /**
+ * Return the string value for the specified key. Look in the nodes which
+ * are specified by this object's list of search scopes. If the value does
+ * not exist then return <code>null</code>.
+ *
+ * @param key
+ * the key to search with
+ * @return String or <code>null</code> if the value does not exist.
+ */
+ protected String internalGet(String key) {
+ return Platform.getPreferencesService().get(key, null, getPreferenceNodes(true));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getFloat(java.lang.String)
+ */
+ public float getFloat(String name) {
+ String value = internalGet(name);
+ if (value == null) {
+ return FLOAT_DEFAULT_DEFAULT;
+ }
+ try {
+ return Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ return FLOAT_DEFAULT_DEFAULT;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getInt(java.lang.String)
+ */
+ public int getInt(String name) {
+ String value = internalGet(name);
+ if (value == null) {
+ return INT_DEFAULT_DEFAULT;
+ }
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ return INT_DEFAULT_DEFAULT;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getLong(java.lang.String)
+ */
+ public long getLong(String name) {
+ String value = internalGet(name);
+ if (value == null) {
+ return LONG_DEFAULT_DEFAULT;
+ }
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ return LONG_DEFAULT_DEFAULT;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#getString(java.lang.String)
+ */
+ public String getString(String name) {
+ String value = internalGet(name);
+ return value == null ? STRING_DEFAULT_DEFAULT : value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#isDefault(java.lang.String)
+ */
+ public boolean isDefault(String name) {
+ if (name == null) {
+ return false;
+ }
+ return (Platform.getPreferencesService().get(name, null, getPreferenceNodes(false))) == null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#needsSaving()
+ */
+ public boolean needsSaving() {
+ return dirty;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#putValue(java.lang.String,
+ * java.lang.String)
+ */
+ public void putValue(String name, String value) {
+ try {
+ // Do not notify listeners
+ silentRunning = true;
+ getStorePreferences().put(name, value);
+ } finally {
+ // Be sure that an exception does not stop property updates
+ silentRunning = false;
+ dirty = true;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+ */
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ removeListenerObject(listener);
+ if (!isListenerAttached()) {
+ disposePreferenceStoreListener();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * double)
+ */
+ public void setDefault(String name, double value) {
+ getDefaultPreferences().putDouble(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * float)
+ */
+ public void setDefault(String name, float value) {
+ getDefaultPreferences().putFloat(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * int)
+ */
+ public void setDefault(String name, int value) {
+ getDefaultPreferences().putInt(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * long)
+ */
+ public void setDefault(String name, long value) {
+ getDefaultPreferences().putLong(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * java.lang.String)
+ */
+ public void setDefault(String name, String defaultObject) {
+ getDefaultPreferences().put(name, defaultObject);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String,
+ * boolean)
+ */
+ public void setDefault(String name, boolean value) {
+ getDefaultPreferences().putBoolean(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setToDefault(java.lang.String)
+ */
+ public void setToDefault(String name) {
+
+ String oldValue = getString(name);
+ String defaultValue = getDefaultString(name);
+ try {
+ silentRunning = true;// Turn off updates from the store
+ // removing a non-existing preference is a no-op so call the Core
+ // API directly
+ getStorePreferences().remove(name);
+ if (!oldValue.equals(defaultValue)) {
+ dirty = true;
+ firePropertyChangeEvent(name, oldValue, defaultValue);
+ }
+
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * double)
+ */
+ public void setValue(String name, double value) {
+ double oldValue = getDouble(name);
+ if (oldValue == value) {
+ return;
+ }
+ try {
+ silentRunning = true;// Turn off updates from the store
+ if (getDefaultDouble(name) == value) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().putDouble(name, value);
+ }
+ dirty = true;
+ firePropertyChangeEvent(name, new Double(oldValue), new Double(value));
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * float)
+ */
+ public void setValue(String name, float value) {
+ float oldValue = getFloat(name);
+ if (oldValue == value) {
+ return;
+ }
+ try {
+ silentRunning = true;// Turn off updates from the store
+ if (getDefaultFloat(name) == value) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().putFloat(name, value);
+ }
+ dirty = true;
+ firePropertyChangeEvent(name, new Float(oldValue), new Float(value));
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * int)
+ */
+ public void setValue(String name, int value) {
+ int oldValue = getInt(name);
+ if (oldValue == value) {
+ return;
+ }
+ try {
+ silentRunning = true;// Turn off updates from the store
+ if (getDefaultInt(name) == value) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().putInt(name, value);
+ }
+ dirty = true;
+ firePropertyChangeEvent(name, Integer.valueOf(oldValue), Integer.valueOf(value));
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * long)
+ */
+ public void setValue(String name, long value) {
+ long oldValue = getLong(name);
+ if (oldValue == value) {
+ return;
+ }
+ try {
+ silentRunning = true;// Turn off updates from the store
+ if (getDefaultLong(name) == value) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().putLong(name, value);
+ }
+ dirty = true;
+ firePropertyChangeEvent(name, Long.valueOf(oldValue), Long.valueOf(value));
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * java.lang.String)
+ */
+ public void setValue(String name, String value) {
+ // Do not turn on silent running here as Strings are propagated
+ if (getDefaultString(name).equals(value)) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().put(name, value);
+ }
+ dirty = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String,
+ * boolean)
+ */
+ public void setValue(String name, boolean value) {
+ boolean oldValue = getBoolean(name);
+ if (oldValue == value) {
+ return;
+ }
+ try {
+ silentRunning = true;// Turn off updates from the store
+ if (getDefaultBoolean(name) == value) {
+ getStorePreferences().remove(name);
+ } else {
+ getStorePreferences().putBoolean(name, value);
+ }
+ dirty = true;
+ firePropertyChangeEvent(name, oldValue ? Boolean.TRUE : Boolean.FALSE, value ? Boolean.TRUE : Boolean.FALSE);
+ } finally {
+ silentRunning = false;// Restart listening to preferences
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPersistentPreferenceStore#save()
+ */
+ public void save() throws IOException {
+ try {
+ getStorePreferences().flush();
+ dirty = false;
+ } catch (BackingStoreException e) {
+ throw new IOException(e.getMessage());
+ }
+
+ }
+
+ /**
+ * Dispose the receiver.
+ */
+ private void disposePreferenceStoreListener() {
+
+ IEclipsePreferences root = (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node(Plugin.PLUGIN_PREFERENCE_SCOPE);
+ try {
+ if (!(root.nodeExists(nodeQualifier))) {
+ return;
+ }
+ } catch (BackingStoreException e) {
+ return;// No need to report here as the node won't have the
+ // listener
+ }
+
+ IEclipsePreferences preferences = getStorePreferences();
+ if (preferences == null) {
+ return;
+ }
+ if (preferencesListener != null) {
+ preferences.removePreferenceChangeListener(preferencesListener);
+ preferencesListener = null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/VisiblePageSingleton.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/VisiblePageSingleton.java
new file mode 100644
index 00000000000..7fafd1364aa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/VisiblePageSingleton.java
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 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:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferencePage;
+
+/**
+ * This singleton has bee created to manage the button ok and apply of preference page.
+ * In the case of button ok pressed, the behavior of eclipse try of apply in the first preference page found.
+ * Here each page has a specific behavior. So to store the preference, the active page is called
+ *
+ */
+public class VisiblePageSingleton {
+
+ private static VisiblePageSingleton instance;
+
+ private IPreferencePage page;
+
+ /**
+ *
+ * @return the instance of the {@link VisiblePageSingleton}
+ */
+ public static VisiblePageSingleton getInstance() {
+ if (instance == null) {
+ instance = new VisiblePageSingleton();
+ }
+ return instance;
+ }
+
+ /**
+ * set the visible page
+ *
+ * @param page
+ * a {@link IPreferencePage} --> {@link DiagramPreferencePage} or {@link AbstractPapyrusPreferencePage}
+ */
+ public void setVisiblePage(IPreferencePage page) {
+ this.page = page;
+ }
+
+ /**
+ *
+ * @return the Visible Page
+ */
+ public IPreferencePage getVisiblePage() {
+ return this.page;
+ }
+
+ /**
+ * call the visisble page in order to store preferences
+ */
+ public void store() {
+ if (this.page instanceof IPapyrusPreferencePage) {
+ ((IPapyrusPreferencePage) (this.page)).storeAllPreferences();
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractApplyValueOnPreferenceKeyDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractApplyValueOnPreferenceKeyDialog.java
new file mode 100644
index 00000000000..3b4a3791000
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractApplyValueOnPreferenceKeyDialog.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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.ui.preferences.dialog;
+
+import java.util.ArrayList;
+
+/**
+ * The Class ApplyValueOnPreferenceKeyDialog display all the preference key and give all selected keys
+ */
+public abstract class AbstractApplyValueOnPreferenceKeyDialog extends AbstractPreferenceKeyDialog {
+
+ /** The checked key. */
+ protected ArrayList<String> checkedKey;
+
+ /**
+ * Instantiates a new apply value on preference key dialog.
+ *
+ * @param keys
+ * the keys
+ */
+ public AbstractApplyValueOnPreferenceKeyDialog(String[] keys) {
+ super(keys);
+ checkedKey = new ArrayList<String>();
+ }
+
+ /**
+ * Gets the key to remove.
+ *
+ * @return the key to remove
+ */
+ public ArrayList<String> getKeyToRemove() {
+ return checkedKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ @Override
+ protected void okPressed() {
+ for (int i = 0; i < keyTable.getItems().length; i++) {
+ if (keyTable.getItems()[i].getChecked()) {
+ checkedKey.add((String) keyTable.getItems()[i].getData());
+ }
+ }
+ super.okPressed();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
+ */
+ @Override
+ protected void cancelPressed() {
+ super.cancelPressed();
+ checkedKey = new ArrayList<String>();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractPreferenceKeyDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractPreferenceKeyDialog.java
new file mode 100644
index 00000000000..14b07d5d618
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/preferences/dialog/AbstractPreferenceKeyDialog.java
@@ -0,0 +1,105 @@
+/*****************************************************************************
+ * 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.ui.preferences.dialog;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.messages.Messages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * The Class AbstractPreferenceKeyDialog display all preference key that are given in parameters
+ */
+public abstract class AbstractPreferenceKeyDialog extends org.eclipse.jface.dialogs.StatusDialog {
+
+ /** The key table. */
+ protected Table keyTable;
+
+ /** The table viewer. */
+ protected TableViewer tableViewer;
+
+ /** The keys. */
+ protected String[] keys;
+
+ /**
+ * Instantiates a new abstract preference key dialog.
+ *
+ * @param keys
+ * the array of preference jy to display
+ */
+ public AbstractPreferenceKeyDialog(String[] keys) {
+ super(new Shell());
+ this.keys = Arrays.copyOf(keys, keys.length);
+ setStatusLineAboveButtons(true);
+ updateStatus(new Status(IStatus.INFO, Activator.PLUGIN_ID, Messages.AbstractPreferenceKeyDialog_WouldYouLikeOverloadPreferences));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ keyTable = new Table(composite, SWT.CHECK | SWT.BORDER);
+ tableViewer = new TableViewer(keyTable);
+ tableViewer.setLabelProvider(createLabelProvider());
+ tableViewer.setContentProvider(createContentProvider());
+
+ TableColumn column = new TableColumn(keyTable, SWT.NONE);
+ column.setWidth(150);
+ column.setText(Messages.AbstractPreferenceKeyDialog_Pref_Kind);
+
+ column = new TableColumn(keyTable, SWT.NONE);
+ column.setWidth(90);
+ column.setText(Messages.AbstractPreferenceKeyDialog_Level);
+
+ column = new TableColumn(keyTable, SWT.NONE);
+ column.setWidth(200);
+ column.setText(Messages.AbstractPreferenceKeyDialog_Localization);
+ tableViewer.setInput(keys);
+ keyTable.setHeaderVisible(true);
+
+
+ return composite;
+
+ }
+
+ /**
+ *
+ * @return
+ * the label provider for the table viewer
+ */
+ protected abstract IBaseLabelProvider createLabelProvider();
+
+ /**
+ *
+ * @return
+ * the content provider for the table viewer
+ */
+ protected abstract IContentProvider createContentProvider();
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositePapyrusContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositePapyrusContentProvider.java
new file mode 100644
index 00000000000..b667228dde5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositePapyrusContentProvider.java
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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.ui.providers;
+
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * A content provider that synthesizes content from multiple other providers.
+ */
+public class CompositePapyrusContentProvider implements IAdaptableContentProvider, IHierarchicContentProvider, IStaticContentProvider {
+
+ private final ITreeContentProvider[] delegates;
+
+ public CompositePapyrusContentProvider(ITreeContentProvider... delegates) {
+ super();
+
+ this.delegates = new ITreeContentProvider[delegates.length];
+ for (int i = 0; i < delegates.length; i++) {
+ // Wrap it or not, as needed
+ this.delegates[i] = DelegatingPapyrusContentProvider.wrap(delegates[i]);
+ }
+ }
+
+ public CompositePapyrusContentProvider(Iterable<? extends ITreeContentProvider> delegates) {
+ this(Iterables.toArray(delegates, ITreeContentProvider.class));
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return Stream.of(delegates)
+ .flatMap(d -> Stream.of(d.getElements(inputElement)))
+ .toArray();
+ }
+
+ @Override
+ public void dispose() {
+ Stream.of(delegates).forEach(ITreeContentProvider::dispose);
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ Stream.of(delegates).forEach(d -> d.inputChanged(viewer, oldInput, newInput));
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return Stream.of(delegates)
+ .flatMap(d -> Stream.of(d.getChildren(parentElement)))
+ .toArray();
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return Stream.of(delegates)
+ .map(d -> d.getParent(element))
+ .filter(Objects::nonNull)
+ .findAny().orElse(null);
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return Stream.of(delegates)
+ .anyMatch(d -> d.hasChildren(element));
+ }
+
+ @Override
+ public Object getAdaptedValue(Object containerElement) {
+ return Stream.of(delegates)
+ .map(IAdaptableContentProvider.class::cast)
+ .map(d -> d.getAdaptedValue(containerElement))
+ .filter(Objects::nonNull)
+ .findAny().orElse(containerElement);
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ return Stream.of(delegates)
+ .map(IHierarchicContentProvider.class::cast)
+ .anyMatch(d -> d.isValidValue(element));
+ }
+
+ @Override
+ public Object[] getElements() {
+ return Stream.of(delegates)
+ .map(IStaticContentProvider.class::cast)
+ .flatMap(d -> Stream.of(d.getElements()))
+ .toArray();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositeSemanticContentProviderFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositeSemanticContentProviderFactory.java
new file mode 100644
index 00000000000..71616365e59
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/CompositeSemanticContentProviderFactory.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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.ui.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+
+/**
+ * Default implementation of a composite content-provider factory.
+ */
+class CompositeSemanticContentProviderFactory implements ISemanticContentProviderFactory {
+ private final List<ISemanticContentProviderFactory> factories;
+
+ CompositeSemanticContentProviderFactory(ISemanticContentProviderFactory first, ISemanticContentProviderFactory second) {
+ super();
+
+ factories = Arrays.asList(first, second);
+ }
+
+ private CompositeSemanticContentProviderFactory(CompositeSemanticContentProviderFactory composite, ISemanticContentProviderFactory other) {
+ super();
+
+ if (other instanceof CompositeSemanticContentProviderFactory) {
+ List<ISemanticContentProviderFactory> otherFactories = ((CompositeSemanticContentProviderFactory) other).factories;
+ factories = new ArrayList<>(composite.factories.size() + otherFactories.size());
+ factories.addAll(composite.factories);
+ factories.addAll(otherFactories);
+ } else {
+ factories = new ArrayList<>(composite.factories.size() + 1);
+ factories.addAll(composite.factories);
+ factories.add(other);
+ }
+ }
+
+ @Override
+ public ITreeContentProvider createSemanticContentProvider(ResourceSet resourceSet) {
+ return DelegatingPapyrusContentProvider.compose(factories.stream()
+ .map(f -> f.createSemanticContentProvider(resourceSet))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public ISemanticContentProviderFactory compose(ISemanticContentProviderFactory other) {
+ return new CompositeSemanticContentProviderFactory(this, other);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/DelegatingPapyrusContentProvider.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/DelegatingPapyrusContentProvider.java
new file mode 100644
index 00000000000..de1ddcce51f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/DelegatingPapyrusContentProvider.java
@@ -0,0 +1,170 @@
+/*****************************************************************************
+ * Copyright (c) 2012, 2016 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 410346
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.providers;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.tools.util.TypeUtils;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * A content-provider implementing the complete set of Papyrus-specific content-provider APIs that
+ * delegates those APIs to another provider according to its actual capabilities.
+ */
+public class DelegatingPapyrusContentProvider implements IAdaptableContentProvider, IHierarchicContentProvider, IStaticContentProvider {
+
+ private static final Object[] NONE = {};
+
+ private final ITreeContentProvider treeDelegate;
+ private final IAdaptableContentProvider adaptableDelegate;
+ private final IHierarchicContentProvider hierarchicDelegate;
+ private final IStaticContentProvider staticDelegate;
+
+ public DelegatingPapyrusContentProvider(ITreeContentProvider delegate) {
+ super();
+
+ treeDelegate = delegate;
+ adaptableDelegate = TypeUtils.as(delegate, IAdaptableContentProvider.class);
+ hierarchicDelegate = TypeUtils.as(delegate, IHierarchicContentProvider.class);
+ staticDelegate = TypeUtils.as(delegate, IStaticContentProvider.class);
+ }
+
+ /**
+ * Obtains a content-provider based on the given {@code provider} that implements all of the
+ * the Papyrus-specific extension protocols.
+ *
+ * @param provider
+ * a tree-content provider
+ * @return a complete provider, which may be a delegating provider or may be the original
+ * {@code provider} if it is already complete
+ */
+ public static ITreeContentProvider wrap(ITreeContentProvider provider) {
+ return ((provider instanceof IAdaptableContentProvider) && (provider instanceof IHierarchicContentProvider) && (provider instanceof IStaticContentProvider))
+ ? provider
+ : new DelegatingPapyrusContentProvider(provider);
+ }
+
+ /**
+ * Obtains a content-provider based on the given providers that implements all of the
+ * the Papyrus-specific extension protocols.
+ *
+ * @param first,&nbsp;second,&nbsp;rest
+ * two or more tree-content providers
+ * @return a complete provider based on the given providers
+ */
+ public static ITreeContentProvider compose(ITreeContentProvider first, ITreeContentProvider second, ITreeContentProvider... rest) {
+ return compose(Lists.asList(first, second, rest));
+ }
+
+ /**
+ * Obtains a content-provider based on the given {@code providers} that implements all of the
+ * the Papyrus-specific extension protocols.
+ *
+ * @param providers
+ * zero or more tree-content providers
+ * @return a complete provider based on the given {@code providers}
+ */
+ public static ITreeContentProvider compose(Iterable<? extends ITreeContentProvider> providers) {
+ ITreeContentProvider result;
+
+ // Obtain optimal result in case of a single provider
+ if (providers instanceof Collection<?>) {
+ Collection<? extends ITreeContentProvider> collection = (Collection<? extends ITreeContentProvider>) providers;
+ switch (collection.size()) {
+ case 0:
+ result = new CompositePapyrusContentProvider();
+ break;
+ case 1:
+ result = wrap(Iterables.getOnlyElement(collection));
+ break;
+ default:
+ result = new CompositePapyrusContentProvider(providers);
+ break;
+ }
+ } else {
+ Iterator<? extends ITreeContentProvider> iter = providers.iterator();
+ if (!iter.hasNext()) {
+ result = new CompositePapyrusContentProvider();
+ } else {
+ ITreeContentProvider provider = iter.next();
+ if (iter.hasNext()) {
+ result = new CompositePapyrusContentProvider(providers);
+ } else {
+ result = wrap(provider);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return treeDelegate.getElements(inputElement);
+ }
+
+ @Override
+ public void dispose() {
+ treeDelegate.dispose();
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ treeDelegate.inputChanged(viewer, oldInput, newInput);
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return treeDelegate.getChildren(parentElement);
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return treeDelegate.getParent(element);
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return treeDelegate.hasChildren(element);
+ }
+
+ @Override
+ public Object getAdaptedValue(Object containerElement) {
+ return (adaptableDelegate == null)
+ ? containerElement
+ : adaptableDelegate.getAdaptedValue(containerElement);
+ }
+
+ @Override
+ public boolean isValidValue(Object element) {
+ return (hierarchicDelegate == null) || hierarchicDelegate.isValidValue(element);
+ }
+
+ @Override
+ public Object[] getElements() {
+ return (staticDelegate == null)
+ ? NONE
+ : staticDelegate.getElements();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/ISemanticContentProviderFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/ISemanticContentProviderFactory.java
new file mode 100644
index 00000000000..05eecf9f087
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/providers/ISemanticContentProviderFactory.java
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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.ui.providers;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.papyrus.infra.core.resource.IModel;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+
+/**
+ * <p>
+ * A protocol for creation of semantic model content providers on EMF resource sets.
+ * </p>
+ * <p>
+ * It is expected that {@link IModel}s representing semantic model content in the
+ * {@link ModelSet} provide adapters of this interface type for the purpose of obtaining
+ * suitable content-providers for presentation of the model content to the user.
+ * Because there there are potentially multiple such {@code IModel}s that have
+ * semantic content, it is possible that multiple content-providers will have to be
+ * combined via the {@link #compose(ISemanticContentProviderFactory)} API.
+ * </p>
+ *
+ * @see IModel
+ * @see #compose(ISemanticContentProviderFactory)
+ */
+@FunctionalInterface
+public interface ISemanticContentProviderFactory {
+ /**
+ * Creates a semantic model content provider on the given {@code ResourceSet}.
+ *
+ * @param resourceSet
+ * a resource set
+ *
+ * @return the semantic model content provider
+ */
+ ITreeContentProvider createSemanticContentProvider(ResourceSet resourceSet);
+
+ /**
+ * Obtains a factory that composes my provider with an{@code other} factory's provider.
+ *
+ * @param other
+ * another semantic content-provider factory
+ * @return the composed factory, which generally creates composed content providers
+ */
+ default ISemanticContentProviderFactory compose(ISemanticContentProviderFactory other) {
+ return new CompositeSemanticContentProviderFactory(this, other);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleEventListener.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleEventListener.java
new file mode 100644
index 00000000000..fb55dabd681
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleEventListener.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 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.ui.services;
+
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+
+/**
+ * Listens to the Lifecycle of an {@link IMultiDiagramEditor}
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface EditorLifecycleEventListener {
+
+ /**
+ * The ServicesRegistry is successfully started
+ *
+ * @param editor
+ */
+ public void postInit(IMultiDiagramEditor editor);
+
+ /**
+ * All the editors are constructed, but not yet displayed
+ *
+ * @param editor
+ */
+ public default void preDisplay(IMultiDiagramEditor editor) {
+ // Pass
+ }
+
+ /**
+ * All the editors are displayed
+ *
+ * @param editor
+ */
+ public void postDisplay(IMultiDiagramEditor editor);
+
+ /**
+ * The editor is about to be closed
+ *
+ * @param editor
+ */
+ public void beforeClose(IMultiDiagramEditor editor);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleManager.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleManager.java
new file mode 100644
index 00000000000..d018ab385d1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/EditorLifecycleManager.java
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.services;
+
+import org.eclipse.papyrus.infra.core.services.IService;
+
+/**
+ * The LifecycleManager for IMultiDiagramEditor
+ *
+ * It notifies its listeners when the state of the editor changes
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface EditorLifecycleManager extends IService {
+
+ public void addEditorLifecycleEventsListener(EditorLifecycleEventListener listener);
+
+ public void removeEditorLifecycleEventsListener(EditorLifecycleEventListener listener);
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/Messages.java
new file mode 100644
index 00000000000..0b8d66d2056
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/Messages.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2015, 2016 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.ui.services;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Translatable strings.
+ */
+class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.ui.services.messages"; //$NON-NLS-1$
+ public static String SaveLayoutBeforeClose_0;
+ public static String SaveLayoutBeforeClose_1;
+ public static String SaveLayoutBeforeClose_2;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/ResourceUpdateService.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/ResourceUpdateService.java
new file mode 100644
index 00000000000..c83e251e17c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/ResourceUpdateService.java
@@ -0,0 +1,292 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (camille.letavernier@cea.fr) - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 437217
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.services;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentMap;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor;
+import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor.DirtyPolicy;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveEventListener;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.progress.UIJob;
+
+import com.google.common.collect.Maps;
+
+/**
+ * A Service to check workspace modifications on current resources
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ResourceUpdateService implements IService, IPartListener {
+
+ protected ServicesRegistry registry;
+
+ protected ModelSet modelSet;
+
+ static int[] handledTypes = new int[] { IResourceChangeEvent.POST_CHANGE, IResourceChangeEvent.PRE_DELETE, IResourceChangeEvent.PRE_CLOSE };
+
+ protected boolean isSaving;
+
+ protected ConcurrentMap<IMultiDiagramEditor, Job> pendingEditorCloseJobs = Maps.newConcurrentMap();
+
+ private final ISaveEventListener preSaveListener = new ISaveEventListener() {
+
+ @Override
+ public void doSaveAs(DoSaveEvent event) {
+ isSaving = true;
+ }
+
+ @Override
+ public void doSave(DoSaveEvent event) {
+ isSaving = true;
+ }
+ };
+
+ private final ISaveEventListener postSaveListener = new ISaveEventListener() {
+
+ @Override
+ public void doSaveAs(DoSaveEvent event) {
+ isSaving = false;
+ }
+
+ @Override
+ public void doSave(DoSaveEvent event) {
+ isSaving = false;
+ }
+ };
+
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ this.registry = servicesRegistry;
+ }
+
+ @Override
+ public void startService() throws ServiceException {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+ modelSet = registry.getService(ModelSet.class);
+ registry.getService(ILifeCycleEventsProvider.class).addAboutToDoSaveListener(preSaveListener);
+ registry.getService(ILifeCycleEventsProvider.class).addPostDoSaveListener(postSaveListener);
+ }
+
+ @Override
+ public void disposeService() throws ServiceException {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
+ modelSet = null;
+ }
+
+ protected void closeEditor() {
+ closeEditor(Collections.<Resource> emptyList(), false);
+ }
+
+ protected void closeEditor(final Collection<? extends Resource> triggeringResources, final boolean reopen) {
+ try {
+ if (!reopen) {
+ registry.remove(SaveLayoutBeforeClose.class.getName());
+ }
+
+ final IMultiDiagramEditor editor = registry.getService(IMultiDiagramEditor.class);
+ if (editor != null) {
+ final IWorkbenchPartSite site = editor.getSite();
+ UIJob closeEditorJob = new UIJob(site.getShell().getDisplay(), NLS.bind("Reload editor {0}", editor.getTitle())) {
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ // Remove the pending job
+ pendingEditorCloseJobs.remove(editor);
+
+ IStatus result = Status.OK_STATUS;
+ monitor = SubMonitor.convert(monitor, IProgressMonitor.UNKNOWN);
+
+ try {
+ IReloadableEditor.ReloadReason reason = reopen ? IReloadableEditor.ReloadReason.RESOURCES_CHANGED : IReloadableEditor.ReloadReason.RESOURCES_DELETED;
+
+ DirtyPolicy dirtyPolicy = DirtyPolicy.getDefault();
+ if (!reopen && !editor.isDirty()) {
+ // Check whether we're deleting one of our own resources. If so, just close
+ URI principalURI = modelSet.getURIWithoutExtension();
+ for (Resource next : triggeringResources) {
+ if (next.getURI().trimFileExtension().equals(principalURI)) {
+ dirtyPolicy = DirtyPolicy.DO_NOT_SAVE;
+ break;
+ }
+ }
+ }
+
+ try {
+ IReloadableEditor.Adapter.getAdapter(editor).reloadEditor(triggeringResources, reason, dirtyPolicy);
+ } catch (CoreException e) {
+ result = e.getStatus();
+ }
+ } finally {
+ monitor.done();
+ }
+
+ return result;
+ }
+ };
+
+ // We are notified usually of at least three resources (*.di, *.notation, *.uml) that are unloaded, but
+ // there's no need to close and re-open the same editor three times
+ if (pendingEditorCloseJobs.putIfAbsent(editor, closeEditorJob) == null) {
+ // Async execution to avoid lock conflicts on the Workspace (Probably owned by this thread, and not the UI thread)
+ IWorkbenchSiteProgressService progressService = site.getService(IWorkbenchSiteProgressService.class);
+ progressService.schedule(closeEditorJob);
+ }
+ }
+ } catch (ServiceException ex) {
+ // Nothing
+ }
+ }
+
+ protected void handleResourcesRemoved(Collection<Resource> emfResources) {
+ closeEditor(emfResources, false);
+ }
+
+ protected void handleResourceChanged(Collection<Resource> emfResources) {
+ closeEditor(emfResources, true);
+ }
+
+ // Copied from org.eclipse.emf.ecore.presentation.EcoreEditor
+ protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener() {
+
+ @Override
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta delta = event.getDelta();
+ try {
+ class ResourceDeltaVisitor implements IResourceDeltaVisitor {
+
+ protected Collection<Resource> changedResources = new ArrayList<Resource>();
+
+ protected Collection<Resource> removedResources = new ArrayList<Resource>();
+
+ @Override
+ public boolean visit(final IResourceDelta delta) {
+ if (delta.getResource().getType() == IResource.FILE) {
+ if (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.CHANGED) {
+ URI resourceURI = URI.createPlatformResourceURI(delta.getFullPath().toString(), true);
+ Resource resource = modelSet.getResource(resourceURI, false);
+ if (resource == null) {
+ // try again, with a pluginURI, see bug 418428
+ URI pluginURI = URI.createPlatformPluginURI(delta.getFullPath().toString(), true);
+ resource = modelSet.getResource(pluginURI, false);
+ }
+ if (resource != null) {
+
+ if (delta.getKind() == IResourceDelta.REMOVED) {
+ removedResources.add(resource);
+ } else {
+ if ((delta.getFlags() & IResourceDelta.MARKERS) != 0) {
+ // Skip markers
+ // DiagnosticDecorator.DiagnosticAdapter.update(resource, markerHelper.getMarkerDiagnostics(resource, (IFile)delta.getResource()));
+ }
+ if ((delta.getFlags() & IResourceDelta.CONTENT) != 0) {
+ // if(!savedResources.remove(resource)) {
+ // changedResources.add(resource);
+ // }
+ if (!isSaving) {
+ changedResources.add(resource);
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ public Collection<Resource> getChangedResources() {
+ return changedResources;
+ }
+
+ public Collection<Resource> getRemovedResources() {
+ return removedResources;
+ }
+ }
+
+ final ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
+
+ delta.accept(visitor);
+
+ if (!visitor.getRemovedResources().isEmpty()) {
+ handleResourcesRemoved(visitor.getRemovedResources());
+ }
+
+ if (!visitor.getChangedResources().isEmpty()) {
+ handleResourceChanged(visitor.getChangedResources());
+ }
+ } catch (CoreException exception) {
+ Activator.log.error(exception);
+ }
+ }
+ };
+
+ @Override
+ public void partActivated(IWorkbenchPart part) {
+ // Nothing
+ }
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPart part) {
+ // Nothing
+ }
+
+ @Override
+ public void partClosed(IWorkbenchPart part) {
+ // Nothing
+ }
+
+ @Override
+ public void partDeactivated(IWorkbenchPart part) {
+ // Nothing
+ }
+
+ @Override
+ public void partOpened(IWorkbenchPart part) {
+ // Nothing
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/SaveLayoutBeforeClose.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/SaveLayoutBeforeClose.java
new file mode 100644
index 00000000000..5b84eadb2cb
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/SaveLayoutBeforeClose.java
@@ -0,0 +1,218 @@
+/*****************************************************************************
+ * Copyright (c) 2014, 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 434983
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.services;
+
+import java.io.IOException;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialogWithToggle;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.internal.commands.TogglePageLayoutStorageHandler;
+import org.eclipse.papyrus.infra.ui.internal.preferences.EditorPreferences;
+import org.eclipse.papyrus.infra.ui.internal.preferences.YesNo;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.LifeCycleEventsProvider;
+
+/**
+ * This service automatically saves the current SashModel before closing the Papyrus editor
+ *
+ * This is useful, as modifications to the SashModel do not dirty the editor
+ *
+ * The save action is not executed if the editor is dirty when it is closed (To ensure model consistency)
+ *
+ * Bug 430976: [SashEditor] Editor layout is not exactly the same when reopening the model
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=430976
+ *
+ * @author Camille Letavernier
+ */
+public class SaveLayoutBeforeClose implements IService {
+
+ private ServicesRegistry registry;
+
+ private EditorLifecycleManager lifecycleManager;
+
+ private EditorLifecycleEventListener lifecycleListener;
+
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ this.registry = servicesRegistry;
+ }
+
+ @Override
+ public void startService() throws ServiceException {
+ installSaveOnClose();
+ }
+
+ protected void installSaveOnClose() {
+ try {
+ lifecycleManager = registry.getService(EditorLifecycleManager.class);
+ if (lifecycleManager == null) {
+ return;
+ }
+ } catch (ServiceException ex) {
+ return;
+ }
+
+ lifecycleListener = new EditorLifecycleEventListener() {
+
+ @Override
+ public void postInit(IMultiDiagramEditor editor) {
+ // Nothing
+ }
+
+ @Override
+ public void postDisplay(IMultiDiagramEditor editor) {
+ checkSharedLayout(editor);
+ }
+
+ @Override
+ public void beforeClose(IMultiDiagramEditor editor) {
+ saveBeforeClose(editor);
+ }
+ };
+
+ lifecycleManager.addEditorLifecycleEventsListener(lifecycleListener);
+ }
+
+ public void saveBeforeClose(IMultiDiagramEditor editor) {
+ if (editor.isDirty()) {
+ return; // User explicitly quit without saving. Do nothing (And if user wants to save during exit, the sashmodel will be saved anyway)
+ }
+
+ ModelSet modelSet; // Required
+ LifeCycleEventsProvider internalLifecycleEventsProvider = null; // Optional
+
+ try {
+ modelSet = registry.getService(ModelSet.class);
+ } catch (ServiceException ex) {
+ return;
+ }
+
+ try {
+ ILifeCycleEventsProvider eventsProvider = registry.getService(ILifeCycleEventsProvider.class);
+ if (eventsProvider instanceof LifeCycleEventsProvider) {
+ internalLifecycleEventsProvider = (LifeCycleEventsProvider) eventsProvider;
+ }
+ } catch (ServiceException ex) {
+ // Ignore: the service is optional
+ }
+
+ SashModel sashModel = (SashModel) modelSet.getModel(SashModel.MODEL_ID);
+
+ try {
+ // We need to send pre- and post-save events, but we can only do that with the internal LifecycleEventsProvider
+ // The ISaveAndDirtyService can only save the whole model, but we just want to save the sash
+ DoSaveEvent event = new DoSaveEvent(registry, editor, true);
+ if (internalLifecycleEventsProvider != null) {
+ internalLifecycleEventsProvider.fireAboutToDoSaveEvent(event);
+ internalLifecycleEventsProvider.fireDoSaveEvent(event);
+ }
+ sashModel.saveModel();
+ if (internalLifecycleEventsProvider != null) {
+ internalLifecycleEventsProvider.firePostDoSaveEvent(event);
+ }
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ }
+ }
+
+ private void checkSharedLayout(IMultiDiagramEditor editor) {
+ try {
+ ModelSet modelSet = registry.getService(ModelSet.class);
+ SashModel sashModel = (SashModel) modelSet.getModel(SashModel.MODEL_ID);
+
+ if (sashModel.isLegacyMode()) {
+ // Have we ever created the private sash model file?
+ URI privateURI = sashModel.getPrivateResourceURI();
+ if (!modelSet.getURIConverter().exists(privateURI, null)) {
+ // Prompt the user
+ promptToEnablePrivateStorage(editor);
+ }
+ }
+ } catch (ServiceException ex) {
+ // Shared layout doesn't matter if there's no model-set
+ }
+ }
+
+ private void promptToEnablePrivateStorage(IMultiDiagramEditor editor) {
+ YesNo preference = EditorPreferences.getInstance().getConvertSharedPageLayoutToPrivate();
+
+ if (preference == YesNo.PROMPT) {
+ MessageDialogWithToggle dlg = MessageDialogWithToggle.openYesNoCancelQuestion(editor.getSite().getShell(),
+ Messages.SaveLayoutBeforeClose_0,
+ Messages.SaveLayoutBeforeClose_1,
+ Messages.SaveLayoutBeforeClose_2, false, null, null);
+
+ switch (dlg.getReturnCode()) {
+ case IDialogConstants.YES_ID:
+ preference = YesNo.YES;
+ break;
+ case IDialogConstants.NO_ID:
+ preference = YesNo.NO;
+ break;
+ default:
+ // User cancelled
+ preference = YesNo.PROMPT;
+ break;
+ }
+
+ if (dlg.getToggleState()) {
+ EditorPreferences.getInstance().setConvertSharedPageLayoutToPrivate(preference);
+ }
+ }
+
+ switch (preference) {
+ case YES:
+ // Change the storage to private
+ new TogglePageLayoutStorageHandler().togglePrivatePageLayout(editor);
+
+ // And save the new layout scheme
+ saveBeforeClose(editor);
+ break;
+ case NO:
+ // Just create the empty resource and save it
+ try {
+ ModelSet modelSet = editor.getServicesRegistry().getService(ModelSet.class);
+ SashModel sashModel = (SashModel) modelSet.getModel(SashModel.MODEL_ID);
+ modelSet.createResource(sashModel.getPrivateResourceURI());
+ saveBeforeClose(editor);
+ } catch (ServiceException e) {
+ // Without a model-set, much else is going wrong, so there's no need to deal
+ // with this here
+ }
+ break;
+ default:
+ // User cancelled
+ break;
+ }
+ }
+
+ @Override
+ public void disposeService() throws ServiceException {
+ registry = null;
+ if (lifecycleManager != null) {
+ lifecycleManager.removeEditorLifecycleEventsListener(lifecycleListener);
+ lifecycleListener = null;
+ lifecycleManager = null;
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/EditorLifecycleManagerImpl.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/EditorLifecycleManagerImpl.java
new file mode 100644
index 00000000000..99a102093f5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/EditorLifecycleManagerImpl.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 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.ui.services.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.services.EditorLifecycleEventListener;
+import org.eclipse.papyrus.infra.ui.services.EditorLifecycleManager;
+
+
+public class EditorLifecycleManagerImpl implements EditorLifecycleManager, InternalEditorLifecycleManager {
+
+ private final Set<EditorLifecycleEventListener> listeners = new HashSet<EditorLifecycleEventListener>();
+
+ @Override
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ // Nothing
+ }
+
+ @Override
+ public void startService() throws ServiceException {
+ // Nothing
+ }
+
+ @Override
+ public void disposeService() throws ServiceException {
+ listeners.clear();
+ }
+
+ @Override
+ public void addEditorLifecycleEventsListener(EditorLifecycleEventListener listener) {
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeEditorLifecycleEventsListener(EditorLifecycleEventListener listener) {
+ listeners.remove(listener);
+ }
+
+ @Override
+ public void firePostInit(final IMultiDiagramEditor editor) {
+ for (final EditorLifecycleEventListener listener : listeners) {
+ SafeRunner.run(new ISafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ listener.postInit(editor);
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Already logged by the SafeRunner
+ }
+ });
+ }
+ }
+
+ @Override
+ public void firePreDisplay(final IMultiDiagramEditor editor) {
+ for (final EditorLifecycleEventListener listener : listeners) {
+ SafeRunner.run(new ISafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ listener.preDisplay(editor);
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Already logged by the SafeRunner
+ }
+ });
+ }
+ }
+
+ @Override
+ public void firePostDisplay(final IMultiDiagramEditor editor) {
+ for (final EditorLifecycleEventListener listener : listeners) {
+ SafeRunner.run(new ISafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ listener.postDisplay(editor);
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Already logged by the SafeRunner
+ }
+ });
+ }
+ }
+
+ @Override
+ public void fireBeforeClose(final IMultiDiagramEditor editor) {
+ for (final EditorLifecycleEventListener listener : listeners) {
+ SafeRunner.run(new ISafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ listener.beforeClose(editor);
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Already logged by the SafeRunner
+ }
+ });
+ }
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/InternalEditorLifecycleManager.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/InternalEditorLifecycleManager.java
new file mode 100644
index 00000000000..97420afd721
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/internal/InternalEditorLifecycleManager.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 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.ui.services.internal;
+
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+
+
+public interface InternalEditorLifecycleManager extends IService {
+
+ /**
+ * Sends the postInit notification for this editor
+ *
+ * @param editor
+ */
+ void firePostInit(IMultiDiagramEditor editor);
+
+ /**
+ * Sets the preDisplay notification for this editor
+ *
+ * @param editor
+ */
+ void firePreDisplay(IMultiDiagramEditor editor);
+
+ /**
+ * Sends the postDisplay notification for this editor
+ *
+ * @param editor
+ */
+ void firePostDisplay(IMultiDiagramEditor editor);
+
+ /**
+ * Sends the beforeClose notification for this Editor
+ *
+ * @param editor
+ */
+ void fireBeforeClose(IMultiDiagramEditor editor);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/messages.properties
new file mode 100644
index 00000000000..a6f77150932
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/services/messages.properties
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2015 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
+#
+
+SaveLayoutBeforeClose_0=Editor Layout Storage
+SaveLayoutBeforeClose_1=This model stores the editor page layout in the DI resource, which if managed in a source control system will share the layout with others. Convert to local (private) storage of the page layout?
+SaveLayoutBeforeClose_2=Remember my decision
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/AbstractCreateMenuFromCommandCategory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/AbstractCreateMenuFromCommandCategory.java
new file mode 100644
index 00000000000..c392791147e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/AbstractCreateMenuFromCommandCategory.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.menus.CommandContributionItem;
+import org.eclipse.ui.menus.CommandContributionItemParameter;
+import org.eclipse.ui.menus.ExtensionContributionFactory;
+import org.eclipse.ui.menus.IContributionRoot;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * Abstract Class to create menu from an Eclipse Command category
+ *
+ * @author VL222926
+ *
+ */
+public abstract class AbstractCreateMenuFromCommandCategory extends ExtensionContributionFactory {
+
+ /** the category of the command contributing to this menu */
+ protected final String commandCateogyId;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param commandCategoryId
+ * the category of the command contributing to this menu
+ */
+ public AbstractCreateMenuFromCommandCategory(final String commandCategoryId) {
+ this.commandCateogyId = commandCategoryId;
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.menus.AbstractContributionFactory#createContributionItems(org.eclipse.ui.services.IServiceLocator, org.eclipse.ui.menus.IContributionRoot)
+ *
+ * @param serviceLocator
+ * @param additions
+ */
+ @Override
+ public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) {
+ // test to know if we can create elements if it is possible...
+ Expression visibleWhen = new Expression() {
+
+ @Override
+ public EvaluationResult evaluate(IEvaluationContext context) throws CoreException {
+ return EvaluationResult.TRUE;
+ }
+ };
+ for (final CommandContributionItem item : addCreationItems(serviceLocator, additions, null)) {
+ additions.addContributionItem(item, visibleWhen);
+ }
+ }
+
+ /**
+ *
+ * @param serviceLocator
+ * @param additions
+ * @param parent
+ * @return
+ */
+ protected List<CommandContributionItem> addCreationItems(final IServiceLocator serviceLocator, final IContributionRoot additions, IContributionManager parent) {
+ final ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class);
+ final List<CommandContributionItem> items = new ArrayList<CommandContributionItem>();
+ final Category category = commandService.getCategory(this.commandCateogyId);
+ final Set<Command> commands = new TreeSet<Command>();
+ commands.addAll(Arrays.asList(commandService.getDefinedCommands()));
+ for (Command command : commands) {
+ Category currentCategory = null;
+ try {
+ currentCategory = command.getCategory();
+ } catch (NotDefinedException e) {
+ Activator.log.debug(e.getLocalizedMessage());
+ continue;
+ }
+ if (command.isDefined() && category.equals(currentCategory)) {
+ final IHandler handler = command.getHandler();
+ if (handler instanceof AbstractHandler) {
+
+ // required!?!?! in some case can avoid the message for handler conflicting (ex : Allocate in SysML NatTable Allocation
+ ((AbstractHandler) handler).setEnabled(null);
+ boolean isEnabled = handler.isEnabled();
+ command.setEnabled(null);
+ ((AbstractHandler) handler).setEnabled(null);
+
+ isEnabled = handler.isEnabled();
+ try {
+ if (isEnabled) {
+ CommandContributionItemParameter p = new CommandContributionItemParameter(serviceLocator, "", command.getId(), SWT.PUSH); //$NON-NLS-1$
+ p.label = command.getDescription();
+ p.icon = EclipseCommandUtils.getCommandIcon(command);
+ CommandContributionItem item = new CommandContributionItem(p);
+ items.add(item);
+ }
+ } catch (NotDefinedException e) {
+ Activator.log.debug(e.getLocalizedMessage());
+ }
+ }
+ }
+ }
+ return items;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/DisplayUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/DisplayUtils.java
new file mode 100644
index 00000000000..27bc70bb5bc
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/DisplayUtils.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.ui.Activator;
+
+
+/**
+ * Util class for display in Papyrus (label providers, etc...)
+ *
+ * @deprecated Use the LabelProviderService instead
+ */
+@Deprecated
+public class DisplayUtils {
+
+ /**
+ * Gets the shared label provider.
+ *
+ * @return Get the current {@link ILabelProvider} or <code>null</code> if
+ * not found
+ */
+ public static ILabelProvider getLabelProvider() {
+ try {
+ ServicesRegistry registry = EditorUtils.getServiceRegistry();
+ return registry == null ? null : registry.getService(ILabelProvider.class);
+ } catch (IllegalStateException e) {
+ // Registry can't be found, do nothing.
+ Activator.log.error(e);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EclipseCommandUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EclipseCommandUtils.java
new file mode 100644
index 00000000000..ace809b60a5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EclipseCommandUtils.java
@@ -0,0 +1,137 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.State;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandImageService;
+import org.eclipse.ui.commands.ICommandService;
+
+/**
+ * This class provides useful methods to manipulate Eclipse Command
+ *
+ * @author vl222926
+ *
+ */
+public class EclipseCommandUtils {
+
+ private EclipseCommandUtils() {
+ // to prevent instanciation
+ }
+
+ public static final String TOGGLE_STATE = "org.eclipse.ui.commands.toggleState"; //$NON-NLS-1$
+
+ public static final String RADIO_STATE = "org.eclipse.ui.commands.radioState"; //$NON-NLS-1$
+
+ public static final String DELETE_COMMAND = "org.eclipse.ui.edit.delete"; //$NON-NLS-1$
+
+ /**
+ *
+ * @param categoryId
+ * a category id
+ * @return
+ * all commands defined for this category
+ */
+ public static final Collection<Command> getAllExistingCommandsInCategory(final String categoryId) {
+ final Set<Command> commands = new TreeSet<Command>();
+ final ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class);
+ final Category category = commandService.getCategory(categoryId);
+ for (final Command command : commandService.getDefinedCommands()) {
+ Category currentCategory = null;
+ try {
+ currentCategory = command.getCategory();
+ } catch (NotDefinedException e) {
+ Activator.log.debug(e.getLocalizedMessage());
+ continue;
+ }
+ if (/* command.isDefined() && */category.equals(currentCategory)) {
+ commands.add(command);
+ }
+ }
+ return commands;
+ }
+
+ /**
+ *
+ * @param command
+ * an Eclipse command
+ * @return
+ * the image descriptor associated to this command
+ */
+ public static final ImageDescriptor getCommandIcon(final Command command) {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ final ICommandImageService service = workbench.getService(ICommandImageService.class);
+ final ImageDescriptor imageDescriptor = service.getImageDescriptor(command.getId());
+ return imageDescriptor;
+ }
+
+ /**
+ *
+ * @param command
+ * an eclipse command
+ * @param newValue
+ * the new boolean value to set to the state of this command
+ */
+ public static final void updateToggleCommandState(final org.eclipse.core.commands.Command command, final boolean newValue) {
+ if (command != null) {
+ final State state = command.getState(TOGGLE_STATE);
+ if (state != null) {
+ state.setValue(newValue);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param command
+ * an eclipse command
+ * @param newValue
+ * the new value to set to the state of this command
+ */
+ public static final void updateRadioCommandState(final org.eclipse.core.commands.Command command, final Object newValue) {
+ if (command != null) {
+ final State state = command.getState(RADIO_STATE);
+ if (state != null) {
+ state.setValue(newValue);
+ }
+ }
+ }
+
+ /**
+ *
+ * @return
+ * the eclipse command service
+ */
+ public static final ICommandService getCommandService() {
+ IWorkbench wb = PlatformUI.getWorkbench();
+ if (wb != null) {
+ IWorkbenchWindow ww = wb.getActiveWorkbenchWindow();
+ if (ww != null) {
+ return ww.getService(ICommandService.class);
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorHelper.java
new file mode 100644
index 00000000000..01802f176fa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorHelper.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ *
+ * a helper for the Editor
+ *
+ */
+public class EditorHelper {
+
+ private EditorHelper() {
+ // nothing to do
+ }
+
+ /**
+ *
+ * @return
+ * the current editor or <code>null</code> if not found
+ */
+ public static final IEditorPart getCurrentEditor() {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) {
+ final IWorkbenchWindow activeWorkbench = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbench != null) {
+ final IWorkbenchPage activePage = activeWorkbench.getActivePage();
+ if (activePage != null) {
+ return activePage.getActiveEditor();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @return
+ * the current active part or <code>null</code> if not found
+ */
+ public static final IWorkbenchPart getActivePart() {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) {
+ final IWorkbenchWindow activeWorkbench = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbench != null) {
+ final IWorkbenchPage activePage = activeWorkbench.getActivePage();
+ if (activePage != null) {
+ return activePage.getActivePart();
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java
new file mode 100644
index 00000000000..6918f42b92d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java
@@ -0,0 +1,721 @@
+/*****************************************************************************
+ * Copyright (c) 2008, 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:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>: Code simplification and NPE
+ * management.
+ * Christian W. Damus (CEA LIST) - API for determining URI of a resource in an editor
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.common.ui.URIEditorInput;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModelUtils;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelMngr;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.DiResourceSet;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.papyrus.infra.ui.editor.CoreMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Set of utility methods for the CoreEditor. <br>
+ * WARNING : Some of these methods rely on
+ * PlatformUI.getWorkbench().getActiveWorkbenchWindow()getActivePage() to lookup
+ * for shared objects owned by the main editor. This doesn't work during the
+ * initialization of the main editor because the main editor is not yet
+ * registered in the Eclipse workbench. This can lead to a null or an exception,
+ * and sometime this can lead to getting the shared object of another main
+ * editor !
+ *
+ * @author cedric dumoulin
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
+ */
+// FIXME throws Exception (eg: NotFoundException) instead of null
+public class EditorUtils {
+
+ /**
+ * Gets the opened multi-diagram editors.
+ *
+ * @return The opened {@link IMultiDiagramEditor} or null if an error
+ * occured.
+ */
+ public static IMultiDiagramEditor[] getMultiDiagramEditors() {
+ // Lookup ServiceRegistry
+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (workbenchWindow == null) {
+ return null;
+ }
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ if (page == null) {
+ return null;
+ }
+ List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>();
+ for (IEditorReference editorRef : page.getEditorReferences()) {
+ IEditorPart editorPart = editorRef.getEditor(false);
+ if (editorPart instanceof IMultiDiagramEditor) {
+ list.add((IMultiDiagramEditor) editorPart);
+ }
+ }
+ return list.toArray(new IMultiDiagramEditor[list.size()]);
+ }
+
+ /**
+ * Returns the editors that are related to to given file.<BR>
+ *
+ * @param file
+ * The file (model, di or notation).
+ * @return The associated editors.
+ */
+ public static IMultiDiagramEditor[] getRelatedEditors(IFile file) {
+ // Get the DI file
+ IFile diFile = DiModelUtils.getRelatedDiFile(file);
+ if (diFile == null || !diFile.exists()) {
+ return new IMultiDiagramEditor[0];
+ }
+
+ IMultiDiagramEditor[] openedEditors = EditorUtils.getMultiDiagramEditors();
+ if (openedEditors == null) {
+ return new IMultiDiagramEditor[0];
+ }
+ List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>(openedEditors.length);
+
+ for (IMultiDiagramEditor editorPart : openedEditors) {
+ if (editorPart.getEditorInput() instanceof IFileEditorInput && diFile.equals(((IFileEditorInput) editorPart.getEditorInput()).getFile())) {
+ list.add(editorPart);
+ }
+ }
+ return list.toArray(new IMultiDiagramEditor[list.size()]);
+ }
+
+ /**
+ * Create an instance of IPageMngr acting on the provided resource. This
+ * instance is suitable to add, remove, close or open diagrams.
+ *
+ * @param diResource
+ * @return The non transactional implementation of IPageMngr
+ */
+ public static IPageManager getIPageMngr(Resource diResource) {
+ return DiSashModelMngr.createIPageMngr(diResource);
+ }
+
+
+ // //////////////////////////////////////////
+ // The following methods are deprecated. They have been replaced by specific
+ // implementations of ServiceUtils (e.g. ServiceUtilsForHandlers, ServiceUtilsForEObject),
+ // which depend on a specific context (ExecutionEvent, EObject, ...) instead of
+ // the active editor
+ // //////////////////////////////////////////
+
+ /**
+ * Gets the {@link IMultiDiagramEditor} interface of the a Eclipse active
+ * editor, if possible, or null if not possible. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if there is no active editor, or if the editor is
+ * not instance of IMultiDiagramEditor. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. Usage of this method is discouraged. Use {@link #getMultiDiagramEditorChecked()} instead.
+ *
+ *
+ * @return Get the current {@link IMultiDiagramEditor} or null if not found.
+ */
+ public static IMultiDiagramEditor getMultiDiagramEditor() {
+ // Lookup ServiceRegistry
+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (workbenchWindow == null) {
+ return null;
+ }
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ if (page == null) {
+ return null;
+ }
+ IEditorPart editor = page.getActiveEditor();
+ if (editor instanceof IMultiDiagramEditor) {
+ return (IMultiDiagramEditor) editor;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Lookup the currently active Diagram from the Papyrus editor. Return the
+ * current Diagram or null if none is active. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if the ServicesRegistry can not be found. <br>
+ * TODO This method introduce dependency on GMF. It can be moved to a GMF
+ * plugin.
+ *
+ * @return The active diagram or null if not found.
+ *
+ * @deprecated The core do make suppositions about the type of nested
+ * Editors, GMF stuff should be moved in GMF projects. In many
+ * case, {@link #lookupActiveNestedIEditor()} can be used.
+ */
+ // @Deprecated
+ // public static Diagram lookupEditorActiveDiagram() {
+ // DiagramEditor diagEditor = lookupActiveDiagramEditor();
+ // return diagEditor == null ? null : diagEditor.getDiagram();
+ // }
+
+ /**
+ * Lookup the currently active Diagram from the Papyrus editor. Return the
+ * current Diagram or null if none is active. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if the ServicesRegistry can not be found. <br>
+ * TODO This method introduce dependency on GMF. It can be moved to a GMF
+ * plugin.
+ *
+ * @return the active diagram editor or null if not found.
+ *
+ * @deprecated The core do make suppositions about the type of nested
+ * Editors, GMF stuff should be moved in GMF projects. In many
+ * case, {@link #lookupActiveNestedIEditor()} can be used.
+ */
+ // @Deprecated
+ // public static DiagramEditor lookupActiveDiagramEditor() {
+ // // Get the active page within the sashcontainer
+ // IEditorPart activeEditor = lookupActiveNestedIEditor();
+ // // Check if it is a GMF DiagramEditor
+ // if(activeEditor instanceof DiagramEditor) {
+ // return ((DiagramEditor)activeEditor);
+ // } else {
+ // // Not found
+ // return null;
+ // }
+ //
+ // }
+
+ /**
+ * Lookup the currently active {@link IEditorPart} from the Papyrus editor.
+ * Return the current nested editor part, or null if it can not be found. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if the ServicesRegistry can not be found. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. An alternative is to use
+ * serviceRegistry.getService(ISashWindowsContainer
+ * .class).getActiveEditor(); <br>
+ * It is preferable to retrieve the ServiceRegistry from elsewhere whenever
+ * it is possible. <br>
+ *
+ *
+ * @return
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static IEditorPart lookupActiveNestedIEditor() {
+ // Get the sashwindow container
+ ISashWindowsContainer container = getSashWindowContainer();
+ // Get the active page within the sashcontainer
+ return container == null ? null : container.getActiveEditor();
+ }
+
+ /**
+ * Lookup the currently active IEditor in the SashSystem. If the currently
+ * eclipse active editor doesn't contains a {@link ISashWindowsContainer},
+ * return null. If the current SashSystem page is not a IEditor, return
+ * null. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if the ServicesRegistry can not be found. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. An alternative is to use
+ * serviceRegistry.getService(ISashWindowsContainer
+ * .class).getActiveSashWindowsPage(); <br>
+ * It is preferable to retrieve the ServiceRegistry from elsewhere whenever
+ * it is possible.
+ *
+ * @return
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static IPage lookupActiveNestedPage() {
+
+ // Get the sashwindow container
+ ISashWindowsContainer container = getSashWindowContainer();
+ // Get the active page within the sashcontainer
+ return container == null ? null : container.getActiveSashWindowsPage();
+ }
+
+ /**
+ *
+ * @return
+ */
+ private static ISashWindowsContainer getSashWindowContainer() {
+
+ try {
+ return getServiceRegistryChecked().getService(ISashWindowsContainer.class);
+ } catch (ServiceException e) {
+ // The contract says that we return null if not found
+ return null;
+ }
+ }
+
+ /**
+ * Gets the di resource set.
+ *
+ * @return Get the current {@link DiResourceSet} or null if not found.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static DiResourceSet getDiResourceSet() {
+ try {
+ ServicesRegistry registry = getServiceRegistry();
+ return registry == null ? null : registry.getService(DiResourceSet.class);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the {@link TransactionalEditingDomain} of the current active Eclipse
+ * Editor. This method should be used only when it is sure that the active
+ * editor exist, and that you want the EditingDomain of this editor. <br>
+ * This method return null if the TransactionalEditingDomain can not be
+ * found. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. An alternative is to use {@link #getTransactionalEditingDomainChecked()} and to catch the
+ * exception. <br>
+ * It is preferable to use {@link #getTransactionalEditingDomain(ServicesRegistry)} whenever it is
+ * possible. <br>
+ * In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
+ * with methods from
+ * org.eclipse.papyrus.uml.diagram.common.util.DiagramCoreServiceUtils <br>
+ * WARNING: This method can return null if there is no Active Editor. This
+ * happen during the editor initialization, especially when there is no
+ * other editor opened.
+ *
+ * @return Get the current {@link TransactionalEditingDomain} or null if not
+ * found
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static TransactionalEditingDomain getTransactionalEditingDomain() {
+ try {
+ ServicesRegistry registry = getServiceRegistry();
+ return registry == null ? null : registry.getService(TransactionalEditingDomain.class);
+ } catch (IllegalStateException e) {
+ // Registry can't be found, do nothing.
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the {@link TransactionalEditingDomain} of the current active Eclipse
+ * Editor. This method should be used only when it is sure that the active
+ * editor exist, and that you want the EditingDomain of this editor. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * It is preferable to use {@link #getTransactionalEditingDomain(ServicesRegistry)} whenever it is
+ * possible. <br>
+ * This method throw a {@link ServiceException} if the
+ * TransactionalEditingDomain can not be found. <br>
+ * In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
+ * with methods from
+ * org.eclipse.papyrus.uml.diagram.common.util.DiagramCoreServiceUtils
+ *
+ *
+ * WARNING: This method throws an exception when no Active Editor is found.
+ * This happen during the editor initialization, especially when there is no
+ * other editor opened.
+ *
+ * @return Get the current {@link TransactionalEditingDomain}
+ * @throws ServiceException
+ * @throws ServiceNotFoundException
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static TransactionalEditingDomain getTransactionalEditingDomainChecked() throws ServiceException {
+ try {
+ ServicesRegistry registry = getServiceRegistryChecked();
+ return registry.getService(TransactionalEditingDomain.class);
+ } catch (IllegalStateException e) {
+ throw new ServiceException(e);
+ } catch (Exception e) {
+ throw new ServiceException(e);
+ }
+ }
+
+ /**
+ * Gets the {@link TransactionalEditingDomain} registered in the {@link ServicesRegistry}.
+ *
+ * @param servicesRegistry
+ * @return
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * </ul>
+ */
+ @Deprecated
+ public static TransactionalEditingDomain getTransactionalEditingDomain(ServicesRegistry registry) {
+ try {
+ return registry.getService(TransactionalEditingDomain.class);
+ } catch (IllegalStateException e) {
+ // Registry can't be found, do nothing.
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the {@link TransactionalEditingDomain} registered in the {@link ServicesRegistry}.
+ *
+ * @param servicesRegistry
+ * @return
+ * @throws ServiceException
+ * If the TransactionalEditingDomain can not be found.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * </ul>
+ */
+ @Deprecated
+ public static TransactionalEditingDomain getTransactionalEditingDomainChecked(ServicesRegistry registry) throws ServiceException {
+ return registry.getService(TransactionalEditingDomain.class);
+ }
+
+ /**
+ * Get the {@link ServicesRegistry}of the currently active eclipse editor. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc. <br>
+ * This method return null if the ServicesRegistry can not be found. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. An alternative is to use {@link #getServiceRegistryChecked()} and
+ * to catch the exception. <br>
+ * It is preferable to retrieve the ServiceRegistry from elsewhere whenever
+ * it is possible. <br>
+ * In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
+ * with methods from
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF
+ *
+ * <br>
+ * WARNING: This method can return null if there is no Active Editor. This
+ * happen during the editor initialization, especially when there is no
+ * other editor opened.
+ *
+ * @return The {@link ServicesRegistry} or null if not found.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ static public ServicesRegistry getServiceRegistry() {
+ // Lookup ServiceRegistry
+ IMultiDiagramEditor editor = getMultiDiagramEditor();
+ return editor == null ? null : (ServicesRegistry) editor.getAdapter(ServicesRegistry.class);
+ }
+
+ /**
+ * Get the service registry of the currently active main editor. <br>
+ * WARNING - This method doesn't work during the initialization of the main
+ * editor. See note in class doc.
+ *
+ * @return The {@link ServicesRegistry} or null if not found.
+ * @throws ServiceException
+ * If an error occurs.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ static public ServicesRegistry getServiceRegistryChecked() throws ServiceException {
+ // Lookup ServiceRegistry
+ IMultiDiagramEditor editor = getMultiDiagramEditor();
+ if (editor == null) {
+ throw new ServiceException("Can't get ServiceRegistry"); //$NON-NLS-1$
+ }
+
+ return editor.getAdapter(ServicesRegistry.class);
+ }
+
+ /**
+ * Get the ISashWindowsContentProvider of the active Eclipse Editor, if
+ * possible. <br>
+ * This method return null if the ServiceRegistry can not be found or if an
+ * error occur. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null. <br>
+ *
+ * @return the ISashWindowsContentProvider from the main editor or null if
+ * not found.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ static public ISashWindowsContentProvider getISashWindowsContentProvider() {
+
+ try {
+ return getServiceRegistryChecked().getService(ISashWindowsContentProvider.class);
+ } catch (ServiceException e) {
+ // The contract says that we return null if not found
+ return null;
+ }
+ }
+
+ /**
+ * Get the ISashWindowsContentProvider of the active Eclipse Editor, if
+ * possible. <br>
+ * This method return null if the ServiceRegistry can not be found or if an
+ * error occur. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ * This method should not be used during the editor initialization phase. <br>
+ * In any case, a check should be done on the returned value that can be
+ * null.
+ *
+ * @return the ISashWindowsContentProvider from the main editor or null if
+ * not found.
+ * @deprecated Check
+ * modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
+ * /cookbook/PapyrusCookBook.odt and use one of the replacement:
+ * <ul>
+ * <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
+ * <li>
+ * org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
+ * <li>
+ * org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers (to be used with care !)</li>
+ * </ul>
+ */
+ @Deprecated
+ public static IPageManager getIPageMngr() {
+
+ try {
+ return getServiceRegistryChecked().getService(IPageManager.class);
+ } catch (ServiceException e) {
+ // The contract says that we return null if not found
+ return null;
+ }
+ }
+
+ /**
+ * Get the Eclipse ActiveEditor.
+ *
+ * @return The active {@link CoreMultiDiagramEditor} or null if not found.
+ * @deprecated Use {@link EditorUtils#getMultiDiagramEditor()}
+ */
+ @Deprecated
+ protected static IEditorPart getWorkbenchActiveEditor() {
+ IMultiDiagramEditor editorPart = getMultiDiagramEditor();
+ if (editorPart instanceof CoreMultiDiagramEditor) {
+ return editorPart;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the {@link IMultiDiagramEditor} interface of the a Eclipse active
+ * editor, if possible, or throw an exception if not possible. <br>
+ * WARNING - This method throw an exception during the initialization of the
+ * main editor. This method throws an exception if there is no active
+ * editor, or if the editor is not instance of IMultiDiagramEditor. <br>
+ * This method is designed to be used by ui actions that interact with the
+ * active editor. <br>
+ *
+ *
+ * @return Get the current {@link IMultiDiagramEditor} or null if not found.
+ * @throws BackboneException
+ * If it is not possible to get an instanceof {@link IMultiDiagramEditor}
+ */
+ public static IMultiDiagramEditor getMultiDiagramEditorChecked() throws BackboneException {
+ IEditorPart editor;
+ try {
+ editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ } catch (NullPointerException e) {
+ // Can't get the active editor
+ throw new BackboneException("Can't get the current Eclipse Active Editor: There is no active editor at this time."); //$NON-NLS-1$
+ }
+
+ if (editor instanceof IMultiDiagramEditor) {
+ return (IMultiDiagramEditor) editor;
+ } else {
+ throw new BackboneException("Can't get an Active Editor instance of IMultiDiagramEditor. (actual type:" + editor.getClass().getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * Obtains the URI of the EMF resource identified by the given editor reference.
+ *
+ * @param editorRef
+ * an editor reference
+ *
+ * @return the best-effort URI of the resource that it edits, or {@code null} if it could not be determined,
+ * including the case when the editor input could not be obtained from the reference
+ */
+ public static URI getResourceURI(IEditorReference editorRef) {
+ try {
+ return getResourceURI(editorRef.getEditorInput());
+ } catch (PartInitException e) {
+ Activator.log.error("Could not obtain editor input from editor reference.", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * Obtains the URI of the EMF resource edited by the given {@code editor}.
+ *
+ * @param editor
+ * an open editor
+ *
+ * @return the best-effort URI of the resource that it edits, or {@code null} if it could not be determined,
+ * such as if the editor input could not be obtained from the editor
+ */
+ public static URI getResourceURI(IEditorPart editor) {
+ return getResourceURI(editor.getEditorInput());
+ }
+
+ /**
+ * Obtains the URI of the EMF resource identified by the given editor input.
+ *
+ * @param editorInput
+ * an editor input
+ *
+ * @return the best-effort URI of the resource that it edits, or {@code null} if it could not be determined
+ */
+ public static URI getResourceURI(IEditorInput editorInput) {
+ URI result = null;
+
+ if (editorInput instanceof IFileEditorInput) {
+ result = URI.createPlatformResourceURI(((IFileEditorInput) editorInput).getFile().getFullPath().toString(), true);
+ } else if (editorInput instanceof URIEditorInput) {
+ result = ((URIEditorInput) editorInput).getURI();
+ } else if (editorInput instanceof IURIEditorInput) {
+ result = URI.createURI(((IURIEditorInput) editorInput).getURI().toASCIIString(), true);
+ } else if (editorInput != null) {
+ // desperation
+ Object adapter = editorInput.getAdapter(URI.class);
+ if (adapter instanceof URI) {
+ result = (URI) adapter;
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ICallableWithProgress.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ICallableWithProgress.java
new file mode 100644
index 00000000000..08d3f1d857b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ICallableWithProgress.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) 2014, 2016 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.ui.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.papyrus.infra.tools.util.IProgressCallable;
+
+/**
+ * The {@link Callable} analogue of an {@link IRunnableWithProgress}.
+ *
+ * @deprecated Use the {@link IProgressCallable} API, instead.
+ */
+@Deprecated
+public interface ICallableWithProgress<V> extends IProgressCallable<V> {
+ /**
+ * Invokes me in a runnable context with a progress monitor.
+ *
+ * @param monitor
+ * the progress monitor to use to display progress and receive
+ * requests for cancellation
+ * @exception InvocationTargetException
+ * if the run method must propagate a checked exception,
+ * it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions are automatically
+ * wrapped in an <code>InvocationTargetException</code> by the calling context
+ * @exception InterruptedException
+ * if the operation detects a request to cancel,
+ * using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing <code>InterruptedException</code>
+ *
+ * @see UIUtil#call(IRunnableContext, ICallableWithProgress)
+ * @see IRunnableContext#run
+ */
+ @Override
+ V call(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException;
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/LocalMemento.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/LocalMemento.java
new file mode 100644
index 00000000000..309542ee425
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/LocalMemento.java
@@ -0,0 +1,285 @@
+/*
+ * 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.ui.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.ui.IMemento;
+
+
+/**
+ * Invocation handler for the dynamic local memento implementation.
+ */
+class LocalMemento implements InvocationHandler {
+
+ private static final Class<?>[] INTERFACES = { IMemento.class };
+
+ private static final Map<Method, Method> delegates = createDelegates();
+
+ private final String type;
+
+ private final String id;
+
+ private final List<IMemento> children = new ArrayList<IMemento>();
+
+ private final Map<String, Object> attributes = new HashMap<String, Object>();
+
+ private String textData;
+
+ LocalMemento(String type, String id) {
+ super();
+
+ this.type = type;
+ this.id = id;
+ }
+
+ static IMemento createMemento(String type, String id) {
+ LocalMemento handler = new LocalMemento(type, id);
+ return (IMemento) Proxy.newProxyInstance(LocalMemento.class.getClassLoader(), INTERFACES, handler);
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Object result = null;
+
+ Method implementation = delegates.get(method);
+ if (implementation == null) {
+ throw new UnsupportedOperationException("dynamic proxy handler does not understand " + method.getName()); //$NON-NLS-1$
+ } else {
+ result = implementation.invoke(this, args);
+ }
+
+ return result;
+ }
+
+ @API
+ String getType() {
+ return type;
+ }
+
+ @API
+ String getID() {
+ return id;
+ }
+
+ @API
+ IMemento createChild(String type) {
+ return createChild(type, null);
+ }
+
+ @API
+ IMemento createChild(String type, String id) {
+ IMemento result = createMemento(type, id);
+ children.add(result);
+ return result;
+ }
+
+ @API
+ IMemento getChild(String type) {
+ IMemento result = null;
+ for (IMemento next : children) {
+ if (type.equals(next.getType())) {
+ result = next;
+ break;
+ }
+ }
+ return result;
+ }
+
+ @API
+ IMemento[] getChildren() {
+ return children.toArray(new IMemento[children.size()]);
+ }
+
+ @API
+ IMemento[] getChildren(String type) {
+ List<IMemento> result = new ArrayList<IMemento>(children.size());
+ for (IMemento next : children) {
+ if (type.equals(next.getType())) {
+ result.add(next);
+ }
+ }
+ return result.toArray(new IMemento[result.size()]);
+ }
+
+ @API
+ Float getFloat(String key) {
+ return coerce(attributes.get(key), Float.class);
+ }
+
+ private <T> T coerce(Object value, Class<T> type) {
+ Object result;
+
+ if (value == null) {
+ result = value;
+ } else if (type.isInstance(value)) {
+ result = value;
+ } else if (Number.class.isAssignableFrom(type) && (value instanceof Number)) {
+ Number number = (Number) value;
+ if (type == Integer.class) {
+ result = number.intValue();
+ } else if (type == Float.class) {
+ result = number.floatValue();
+ } else {
+ throw new IllegalArgumentException("unsupported numeric type: " + type.getSimpleName()); //$NON-NLS-1$
+ }
+ } else if (Number.class.isAssignableFrom(type) && (value instanceof String)) {
+ String string = (String) value;
+ if (type == Integer.class) {
+ result = Integer.valueOf(string);
+ } else if (type == Float.class) {
+ result = Float.valueOf(string);
+ } else {
+ throw new IllegalArgumentException("unsupported numeric type: " + type.getSimpleName()); //$NON-NLS-1$
+ }
+ } else if (type == Boolean.class) {
+ // We know the value isn't a Boolean, otherwise we would have handled it already
+ if (value instanceof String) {
+ result = Boolean.valueOf((String) value);
+ } else {
+ throw new IllegalArgumentException("unsupported boolean conversion from type: " + ((value == null) ? "null" : value.getClass().getSimpleName())); //$NON-NLS-1$
+ }
+ } else if (type == String.class) {
+ result = String.valueOf(value);
+ } else {
+ throw new IllegalArgumentException("unsupported attribute type: " + type.getSimpleName()); //$NON-NLS-1$
+ }
+
+ return type.cast(result);
+ }
+
+ @API
+ Integer getInteger(String key) {
+ return coerce(attributes.get(key), Integer.class);
+ }
+
+ @API
+ String getString(String key) {
+ return coerce(attributes.get(key), String.class);
+ }
+
+ @API
+ Boolean getBoolean(String key) {
+ return coerce(attributes.get(key), Boolean.class);
+ }
+
+ @API
+ String getTextData() {
+ return textData;
+ }
+
+ @API
+ String[] getAttributeKeys() {
+ return attributes.keySet().toArray(new String[attributes.size()]);
+ }
+
+ @API
+ void putFloat(String key, float value) {
+ attributes.put(key, value);
+ }
+
+ @API
+ void putInteger(String key, int value) {
+ attributes.put(key, value);
+ }
+
+ @API
+ void putString(String key, String value) {
+ attributes.put(key, value);
+ }
+
+ @API
+ void putBoolean(String key, boolean value) {
+ attributes.put(key, value);
+ }
+
+ @API
+ void putTextData(String data) {
+ textData = data;
+ }
+
+ private boolean isLocalMemento(IMemento memento) {
+ return (memento != null) && Proxy.isProxyClass(memento.getClass()) && ((Proxy.getInvocationHandler(memento) instanceof LocalMemento));
+ }
+
+ @API
+ void putMemento(IMemento memento) {
+ if (!isLocalMemento(memento)) {
+ throw new IllegalArgumentException("memento is not a local memento"); //$NON-NLS-1$
+ }
+ children.add(memento);
+ }
+
+ @Override
+ @API(owner = Object.class)
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+
+ append(result, 0);
+
+ return result.toString();
+ }
+
+ private void append(StringBuilder buf, int depth) {
+ // Indent
+ for (int i = 0; i < depth; i++) {
+ buf.append(" "); //$NON-NLS-1$
+ }
+
+ buf.append("LocalMemento(");//$NON-NLS-1$
+ buf.append(type);
+ if (id != null) {
+ buf.append('[').append(id).append(']');
+ }
+ buf.append(") ").append(attributes); //$NON-NLS-1$
+ buf.append('\n');
+
+ final int nextDepth = depth + 1;
+ for (IMemento next : children) {
+ ((LocalMemento) Proxy.getInvocationHandler(next)).append(buf, nextDepth);
+ }
+ }
+
+ private static Map<Method, Method> createDelegates() {
+ Map<Method, Method> result = new HashMap<Method, Method>();
+
+ for (Method implementation : LocalMemento.class.getDeclaredMethods()) {
+ if (implementation.isAnnotationPresent(API.class)) {
+ try {
+ Method api = implementation.getAnnotation(API.class).owner().getMethod(implementation.getName(), implementation.getParameterTypes());
+ result.put(api, implementation);
+ } catch (NoSuchMethodException e) {
+ throw new LinkageError("Incompatible IMemento API change: " + implementation.getName());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ private @interface API {
+
+ Class<?> owner() default IMemento.class;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/PapyrusImageUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/PapyrusImageUtils.java
new file mode 100644
index 00000000000..ee0d9fb314f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/PapyrusImageUtils.java
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.papyrus.infra.ui.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Services to access to Papyrus images
+ *
+ * @author tristan faure
+ *
+ */
+public class PapyrusImageUtils {
+
+ private static final String default_icon_32 = "/icons/papyrus/32x32/Papyrus_32x32_t.gif"; //$NON-NLS-1$
+
+ private static final String default_icon = "/icons/papyrus/Papyrus.gif"; //$NON-NLS-1$
+
+ /**
+ * get the default icon for Papyrus the image does not have to be disposed
+ * as it is registered in an ImageRegistry
+ *
+ * @return the Image
+ */
+ public static Image getDefaultIcon() {
+ return getIcon(default_icon);
+ }
+
+ /**
+ * get the default icon 32x32 for Papyrus the image does not have to be
+ * disposed as it is registered in an ImageRegistry
+ *
+ * @return the Image
+ */
+ public static Image getDefaultIcon32() {
+ return getIcon(default_icon_32);
+ }
+
+ private static Image getIcon(String path) {
+ String key = Activator.PLUGIN_ID + path;
+ Image result = JFaceResources.getImageRegistry().get(key);
+ if (result == null) {
+ URL url = Activator.getDefault().getBundle().getEntry(path);
+ try {
+ result = new Image(Display.getDefault(), url.openStream());
+ JFaceResources.getImageRegistry().put(key, result);
+ } catch (IOException e) {
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/SelectionHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/SelectionHelper.java
new file mode 100644
index 00000000000..5132a841f4c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/SelectionHelper.java
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author VL222926
+ *
+ */
+public class SelectionHelper {
+
+ /**
+ * Constructor.
+ *
+ */
+ private SelectionHelper() {
+ // to avoid instanciation
+ }
+
+ /**
+ *
+ * @return
+ * the selection service or <code>null</code> if not found
+ *
+ */
+ public static final ISelectionService getSelectionService() {
+ IWorkbench wb = PlatformUI.getWorkbench();
+ if (wb != null) {
+ // don't work
+ // ISelectionService s1 = (ISelectionService) wb.getService(ISelectionService.class);
+ IWorkbenchWindow ww = wb.getActiveWorkbenchWindow();
+ if (ww != null) {
+ return (ISelectionService) ww.getService(ISelectionService.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @return
+ * the current selection or an empty selection. can't be <code>null</code>
+ */
+ public static final ISelection getCurrentSelection() {
+ ISelectionService selectionService = getSelectionService();
+ if (selectionService != null) {
+ ISelection currentSelection = selectionService.getSelection();
+ if (currentSelection != null) {
+ return currentSelection;
+ }
+ }
+ return StructuredSelection.EMPTY;
+ }
+
+ /**
+ *
+ * @param viewId
+ * the id of the view for which we want the selection
+ * @return
+ * the current selection for the view, the returned value can't be <code>null</code>
+ */
+ public static final ISelection getCurrentSelection(String viewId) {
+ ISelectionService selectionService = getSelectionService();
+ if (selectionService != null) {
+ ISelection currentSelection = selectionService.getSelection(viewId);
+ if (currentSelection != null) {
+ return currentSelection;
+ }
+ }
+ return StructuredSelection.EMPTY;
+ }
+
+ /**
+ *
+ * @return
+ * a structured selection.
+ * the returned value can't be <code>null</code>
+ */
+ public static final IStructuredSelection getCurrentStructuredSelection() {
+ ISelection selection = getCurrentSelection();
+ if (selection instanceof IStructuredSelection) {
+ return (IStructuredSelection) selection;
+ }
+ return StructuredSelection.EMPTY;
+ }
+
+ /**
+ *
+ * @param viewId
+ * the id of the view for which we want the selection
+ * @return
+ * the current selection for the view, the returned value can't be <code>null</code>
+ */
+ public static final IStructuredSelection getCurrentStructuredSelection(String viewId) {
+ ISelection selection = getCurrentSelection(viewId);
+ if (selection instanceof IStructuredSelection) {
+ return (IStructuredSelection) selection;
+ }
+ return StructuredSelection.EMPTY;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForActionHandlers.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForActionHandlers.java
new file mode 100644
index 00000000000..917a41e8688
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForActionHandlers.java
@@ -0,0 +1,149 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 LIFL, 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:
+ * Cedric Dumoulin (LIFL) cedric.dumoulin@lifl.fr - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.ui.util;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Set of utility methods for accessing core Services. This class provide
+ * methods to access the Papyrus well known services. This class is designed to
+ * be used from ui Action Handlers or from any code relying on the Eclipse
+ * Active Editor. <br>
+ * All methods from this class rely on the Eclipse Active Editor, which should
+ * be an instance of {@link IMultiDiagramEditor}. If this is not the case,
+ * methods throw an exception {@link ServiceException}.
+ *
+ * @author cedric dumoulin
+ *
+ * @deprecated 0.10: Use org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForHandlers instead
+ */
+@Deprecated
+public class ServiceUtilsForActionHandlers extends AbstractServiceUtils<Void> {
+
+ private ServiceUtilsForActionHandlers() {
+ // Singleton
+ }
+
+ private final static ServiceUtilsForActionHandlers instance = new ServiceUtilsForActionHandlers();
+
+ /**
+ * Get the singleton instance of the class.
+ *
+ * @return
+ */
+ public static final ServiceUtilsForActionHandlers getInstance() {
+ return instance;
+ }
+
+ @Override
+ public ServicesRegistry getServiceRegistry(Void from) throws ServiceException {
+ return getServiceRegistry();
+ }
+
+ /**
+ * Get the service registry from the specified parameter.
+ *
+ * @param from
+ * @return
+ */
+ public ServicesRegistry getServiceRegistry() throws ServiceException {
+ ServicesRegistry serviceRegistry = getContextualServiceRegistry();
+ if (serviceRegistry != null) {
+ return serviceRegistry;
+ }
+
+ // Not found
+ throw new ServiceNotFoundException("Can't get the ServiceRegistry from current Eclipse Active Editor"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets the {@link TransactionalEditingDomain} registered in the {@link ServicesRegistry}.
+ *
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public TransactionalEditingDomain getTransactionalEditingDomain() throws ServiceException {
+ return getServiceRegistry().getService(TransactionalEditingDomain.class);
+ }
+
+ /**
+ * Gets the {@link IPageManager} registered in the {@link ServicesRegistry}.
+ *
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public IPageManager getIPageManager() throws ServiceException {
+ return getServiceRegistry().getService(IPageManager.class);
+ }
+
+ /**
+ * Gets the {@link IPageMngr} registered in the {@link ServicesRegistry}.
+ *
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public ModelSet getModelSet() throws ServiceException {
+ return getServiceRegistry().getService(ModelSet.class);
+ }
+
+ /**
+ * Gets the {@link ILifeCycleEventsProvider} registered in the {@link ServicesRegistry}.
+ *
+ * @param from
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public ILifeCycleEventsProvider getILifeCycleEventsProvider() throws ServiceException {
+ return getServiceRegistry().getService(ILifeCycleEventsProvider.class);
+ }
+
+ /**
+ * Gets the {@link ISashWindowsContainer} registered in the {@link ServicesRegistry}.
+ *
+ * @param from
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public ISashWindowsContainer getISashWindowsContainer() throws ServiceException {
+ return getServiceRegistry().getService(ISashWindowsContainer.class);
+ }
+
+ /**
+ * Gets the {@link IEditorPart} of the currently nested active editor.
+ *
+ * @param from
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public IEditorPart getNestedActiveIEditorPart() throws ServiceException {
+ return getISashWindowsContainer().getActiveEditor();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForHandlers.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForHandlers.java
new file mode 100644
index 00000000000..aec185cc30e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForHandlers.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright (c) 2012, 2016 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 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+/**
+ * ServicesUtils based on the Handler's ExecutionEvent
+ *
+ * It first tests the current selection, then the IWorkbenchPart on which the handler is executed.
+ * The IWorkbenchPart is expected to be adaptable to a ServiceRegistry.
+ *
+ * @author Camille Letavernier
+ *
+ * @see ServiceUtilsForSelection
+ */
+public class ServiceUtilsForHandlers extends AbstractServiceUtils<ExecutionEvent> {
+
+ private ServiceUtilsForHandlers() {
+ // Singleton
+ }
+
+ /**
+ * Gets the {@link IEditorPart} of the currently nested active editor.
+ *
+ * @param from
+ * @return
+ * @throws ServiceException
+ * If an error occurs while getting the requested service.
+ */
+ public IEditorPart getNestedActiveIEditorPart(ExecutionEvent from) throws ServiceException {
+ return getService(ISashWindowsContainer.class, from).getActiveEditor();
+ }
+
+ @Override
+ public ServicesRegistry getServiceRegistry(ExecutionEvent from) throws ServiceException {
+
+ if (from == null) {
+ return getContextualServiceRegistry();
+ }
+
+ Object context = from.getApplicationContext();
+
+ if (context instanceof IEvaluationContext) {
+ IEvaluationContext evaluationContext = (IEvaluationContext) context;
+
+ // Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one)
+ Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite");
+ if (workbenchPartSite instanceof IWorkbenchPartSite) {
+ IWorkbenchPartSite site = (IWorkbenchPartSite) workbenchPartSite;
+ Object registry = site.getAdapter(ServicesRegistry.class);
+ if (registry != null && registry instanceof ServicesRegistry) {
+ return (ServicesRegistry) registry;
+ }
+
+ // Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one)
+ IWorkbenchPart workbenchPart = site.getPart();
+ registry = workbenchPart.getAdapter(ServicesRegistry.class);
+ if (registry != null && registry instanceof ServicesRegistry) {
+ return (ServicesRegistry) registry;
+ }
+ }
+
+ Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+
+ ServicesRegistry registry;
+
+ // Try to resolve the ServicesRegistry from the current selection
+ if (selection instanceof ISelection && !((ISelection) selection).isEmpty()) {
+ try {
+ registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection) selection);
+ if (registry != null) {
+ return registry;
+ }
+ } catch (ServiceException ex) {
+ // Ignore and try another ServiceUtils
+ }
+ }
+
+ // We couldn't retrieve the ServiceRegistry from the current selection.
+
+ // Try to adapt the active part to the ServicesRegistry
+ IWorkbenchPart part = (IWorkbenchPart) evaluationContext.getVariable(ISources.ACTIVE_PART_NAME);
+ registry = (part).getAdapter(ServicesRegistry.class);
+ if (registry != null) {
+ return registry;
+ }
+ }
+
+ throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); //$NON-NLS-1$
+ }
+
+
+
+ public static ServiceUtilsForHandlers getInstance() {
+ return instance;
+ }
+
+ private static final ServiceUtilsForHandlers instance = new ServiceUtilsForHandlers();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForIEvaluationContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForIEvaluationContext.java
new file mode 100644
index 00000000000..015a5e5076e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForIEvaluationContext.java
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ * Copyright (c) 2012, 2016 Cedric Dumoulin, 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:
+ * Cedric Dumoulin - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+/**
+ * ServicesUtils based on the Handler's IEvaluationContext.
+ * This class can be used for both the {@link AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)} and the {@link AbstractHandler#setEnabled(Object)} methods.
+ *
+ *
+ * @author Cedric Dumoulin
+ *
+ */
+public class ServiceUtilsForIEvaluationContext extends AbstractServiceUtils<IEvaluationContext> {
+
+ private ServiceUtilsForIEvaluationContext() {
+ // Singleton
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils#getServiceRegistry(java.lang.Object)
+ *
+ * @param from
+ * @return
+ * @throws ServiceException
+ */
+ @Override
+ public ServicesRegistry getServiceRegistry(IEvaluationContext from) throws ServiceException {
+
+ if (from == null) {
+ return getContextualServiceRegistry();
+ }
+
+ IEvaluationContext evaluationContext = from;
+
+ // Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one)
+ Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite");
+ if (workbenchPartSite instanceof IWorkbenchPartSite) {
+ IWorkbenchPartSite site = (IWorkbenchPartSite) workbenchPartSite;
+ Object registry = site.getAdapter(ServicesRegistry.class);
+ if (registry != null && registry instanceof ServicesRegistry) {
+ return (ServicesRegistry) registry;
+ }
+
+ // Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one)
+ IWorkbenchPart workbenchPart = site.getPart();
+ registry = workbenchPart.getAdapter(ServicesRegistry.class);
+ if (registry != null && registry instanceof ServicesRegistry) {
+ return (ServicesRegistry) registry;
+ }
+ }
+
+ Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+
+ ServicesRegistry registry;
+
+ // Try to resolve the ServicesRegistry from the current selection
+ if (selection instanceof ISelection && !((ISelection) selection).isEmpty()) {
+ try {
+ registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection) selection);
+ if (registry != null) {
+ return registry;
+ }
+ } catch (ServiceException ex) {
+ // Ignore and try another ServiceUtils
+ }
+ }
+
+ // We couldn't retrieve the ServiceRegistry from the current selection.
+
+ // Try to adapt the active part to the ServicesRegistry
+ Object _part = evaluationContext.getVariable(ISources.ACTIVE_PART_NAME);
+ if (_part instanceof IWorkbenchPart) {
+ IWorkbenchPart part = (IWorkbenchPart) _part;
+ registry = (part).getAdapter(ServicesRegistry.class);
+ if (registry != null) {
+ return registry;
+ }
+ }
+
+
+ // nothing found
+ throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); //$NON-NLS-1$
+ }
+
+ public static ServiceUtilsForIEvaluationContext getInstance() {
+ return instance;
+ }
+
+ private static final ServiceUtilsForIEvaluationContext instance = new ServiceUtilsForIEvaluationContext();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForSelection.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForSelection.java
new file mode 100644
index 00000000000..f3a799d303a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForSelection.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+
+/**
+ * ServiceUtils based on an ISelection.
+ *
+ * Expects an IStructuredSelection containing at least one EObject (It then relies on ServiceUtilsForEObject to retrieve the ServicesRegistry)
+ *
+ * @author Camille Letavernier
+ */
+public class ServiceUtilsForSelection extends AbstractServiceUtils<ISelection> {
+
+ private ServiceUtilsForSelection() {
+ // Singleton
+ }
+
+ private static ServiceUtilsForSelection instance = new ServiceUtilsForSelection();
+
+ public static ServiceUtilsForSelection getInstance() {
+ return instance;
+ }
+
+ @Override
+ public ServicesRegistry getServiceRegistry(ISelection from) throws ServiceException {
+ if (from instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) from;
+ Iterator<?> selectionIterator = selection.iterator();
+ while (selectionIterator.hasNext()) {
+ Object selectedElement = selectionIterator.next();
+ EObject selectedEObject = EMFHelper.getEObject(selectedElement);
+ if (selectedEObject != null) {
+ return ServiceUtilsForEObject.getInstance().getServiceRegistry(selectedEObject);
+ }
+ }
+ }
+
+ throw new ServiceException("Cannot retrieve the ServiceRegistry"); //$NON-NLS-1$
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForWorkbenchPage.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForWorkbenchPage.java
new file mode 100644
index 00000000000..624257964cc
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/ServiceUtilsForWorkbenchPage.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * A ServiceUtils implementation for manipulating the Papyrus services from an IWorkbenchPage
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ServiceUtilsForWorkbenchPage extends AbstractServiceUtils<IWorkbenchPage> {
+
+ @Override
+ public ServicesRegistry getServiceRegistry(IWorkbenchPage from) throws ServiceException {
+ IAdaptable adaptable = null;
+ if (from instanceof IAdaptable) {
+ adaptable = (IAdaptable) from;
+ } else if (from != null) {
+ // 421392: [Model Explorer] Link with Editor does not work properly
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421392
+
+ // Since Eclipse 4.4, the concrete WorkbenchPage is not IAdaptable anymore.
+ // Try the ActivePart
+ adaptable = from.getActivePart();
+ }
+
+ if (adaptable != null) {
+ ServicesRegistry registry = (ServicesRegistry) adaptable.getAdapter(ServicesRegistry.class);
+ if (registry != null) {
+ return registry;
+ }
+ }
+
+
+ throw new ServiceException("Cannot resolve the ServiceRegistry from the IWorkbenchPage. Page: " + from); //$NON-NLS-1$
+ }
+
+ public static ServiceUtilsForWorkbenchPage getInstance() {
+ return instance;
+ }
+
+ private static ServiceUtilsForWorkbenchPage instance = new ServiceUtilsForWorkbenchPage();
+
+ private ServiceUtilsForWorkbenchPage() {
+ // Singleton
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/TransactionUIHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/TransactionUIHelper.java
new file mode 100644
index 00000000000..825a99386a3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/TransactionUIHelper.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2014, 2016 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 465416
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.ui.util;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+
+/**
+ * Helper utilities for working with transactions on the UI thread.
+ */
+public class TransactionUIHelper {
+
+ /**
+ * Create a privileged runnable with progress, which is like a regular {@linkplain TransactionalEditingDomain#createPrivilegedRunnable(Runnable)
+ * privileged runnable} except that it is given a progress monitor for progress reporting.
+ * This enables execution of monitored runnables on the modal-context thread using the transaction borrowed from the UI thread.
+ *
+ * @param domain
+ * an editing domain
+ * @param runnable
+ * a runnable with progress that is to borrow the {@code domain}'s active transaction on the modal context thread
+ * @return the privileged runnable, ready to pass into the progress service or other such API
+ */
+ public static IRunnableWithProgress createPrivilegedRunnableWithProgress(TransactionalEditingDomain domain, final IRunnableWithProgress runnable) {
+ final IProgressMonitor monitorHolder[] = { null };
+
+ final Runnable privileged = domain.createPrivilegedRunnable(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ runnable.run(monitorHolder[0]);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new WrappedException(e);
+ }
+ }
+ });
+
+ return new IRunnableWithProgress() {
+
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ monitorHolder[0] = monitor;
+
+ try {
+ privileged.run();
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException(e.getLocalizedMessage());
+ } catch (WrappedException e) {
+ Exception unwrapped = e.exception();
+ if (unwrapped instanceof InvocationTargetException) {
+ throw (InvocationTargetException) unwrapped;
+ } else if (unwrapped instanceof InterruptedException) {
+ throw (InterruptedException) unwrapped;
+ } else {
+ throw e;
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/UIUtil.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/UIUtil.java
new file mode 100644
index 00000000000..343bcdeba56
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/UIUtil.java
@@ -0,0 +1,706 @@
+/*
+ * Copyright (c) 2014, 2016 CEA, 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 (CEA) - Initial API and implementation
+ * Christian W. Damus - bug 399859
+ * Christian W. Damus - bug 451557
+ * Christian W. Damus - bug 485220
+ *
+ */
+package org.eclipse.papyrus.infra.ui.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.emf.common.util.AbstractTreeIterator;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.IServiceRegistryProvider;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.infra.tools.util.IExecutorService;
+import org.eclipse.papyrus.infra.tools.util.IProgressCallable;
+import org.eclipse.papyrus.infra.tools.util.IProgressRunnable;
+import org.eclipse.papyrus.infra.tools.util.Iterators2;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+
+import com.google.common.collect.Iterators;
+
+
+/**
+ * Miscellaneous general-purpose UI utilities.
+ */
+public class UIUtil {
+
+ /**
+ * Not instantiable by clients.
+ */
+ private UIUtil() {
+ super();
+ }
+
+ /**
+ * Create an executor that runs tasks asynchronously on the UI thread. If you need synchronous execution, schedule {@link Future}s and {@linkplain Future#get() wait} for them.
+ *
+ * @param display
+ * the display on which thread to execute tasks
+ *
+ * @return the executor
+ */
+ public static IExecutorService createUIExecutor(Display display) {
+ return new DisplayExecutorService(display);
+ }
+
+ /**
+ * Create an executor that runs tasks asynchronously on an observable {@link Realm}. If you need synchronous execution, schedule {@link Future}s and {@linkplain Future#get() wait} for them.
+ *
+ * @param realm
+ * the observable realm on which thread to execute tasks
+ *
+ * @return the executor
+ */
+ public static ExecutorService createObservableExecutor(Realm realm) {
+ return new RealmExecutorService(realm);
+ }
+
+ /**
+ * Creates a local memento that is not persistable and is not based on an XML document. This is useful for capturing the
+ * state of UI elements locally in cases where persistence of the memento is not required.
+ *
+ * @return the memento
+ */
+ public static IMemento createLocalMemento() {
+ return LocalMemento.createMemento("__anonymous__", null); //$NON-NLS-1$
+ }
+
+ /**
+ * Synchronously invokes a {@code callable} on the given {@code display}'s thread.
+ *
+ * @param display
+ * a display
+ * @param callable
+ * a callable to invoke
+ * @return the callable's result (which, because this method is synchronous, will be ready)
+ *
+ * @see #asyncCall(Display, Callable)
+ * @see #createUIExecutor(Display)
+ */
+ public static <V> Future<V> syncCall(Display display, Callable<V> callable) {
+ final FutureTask<V> result = new FutureTask<V>(callable);
+ display.syncExec(result);
+ return result;
+ }
+
+ /**
+ * Synchronously invokes a {@code callable} on the default display thread.
+ *
+ * @param callable
+ * a callable to invoke
+ * @return the callable's result (which, because this method is synchronous, will be ready)
+ *
+ * @see #syncCall(Display, Callable)
+ * @see #asyncCall(Callable)
+ * @see #createUIExecutor(Display)
+ */
+ public static <V> Future<V> syncCall(Callable<V> callable) {
+ return syncCall(Display.getDefault(), callable);
+ }
+
+ /**
+ * Asynchronously invokes a {@code callable} on the given {@code display}'s thread.
+ *
+ * @param display
+ * a display
+ * @param callable
+ * a callable to invoke
+ * @return the callable's result
+ *
+ * @see #syncCall(Display, Callable)
+ * @see #createUIExecutor(Display)
+ */
+ public static <V> Future<V> asyncCall(Display display, Callable<V> callable) {
+ final FutureTask<V> result = new FutureTask<V>(callable);
+ display.asyncExec(result);
+ return result;
+ }
+
+ /**
+ * Asynchronously invokes a {@code callable} on the default display thread.
+ *
+ * @param callable
+ * a callable to invoke
+ * @return the callable's result
+ *
+ * @see #asyncCall(Display, Callable)
+ * @see #syncCall(Callable)
+ * @see #createUIExecutor(Display)
+ */
+ public static <V> Future<V> asyncCall(Callable<V> callable) {
+ return asyncCall(Display.getDefault(), callable);
+ }
+
+ /**
+ * Calls a {@code callable} in the given {@code context}.
+ *
+ * @param fork
+ * {@code true} if the runnable should be run in a separate thread,
+ * and {@code false} to run in the same thread
+ * @param cancelable
+ * {@code true} to enable the cancellation, and {@code false} to make the operation uncancellable
+ * @param runnable
+ * the runnable to run
+ *
+ * @exception InvocationTargetException
+ * wraps any exception or error which occurs
+ * while running the runnable
+ * @exception InterruptedException
+ * propagated by the context if the runnable
+ * acknowledges cancellation by throwing this exception. This should not be thrown
+ * if {@code cancelable} is {@code false}.
+ *
+ * @deprecated Use the {@link #call(IRunnableContext, boolean, boolean, IProgressCallable)} or
+ * {@link IExecutorService#submit(IProgressCallable)} API, instead.
+ */
+ @Deprecated
+ public static <V> V call(IRunnableContext context, boolean fork, boolean cancelable, ICallableWithProgress<V> callable) throws InvocationTargetException, InterruptedException {
+ return call(context, fork, cancelable, (IProgressCallable<V>) callable);
+ }
+
+ /**
+ * Calls a {@code callable} in the given {@code context}.
+ *
+ * @param fork
+ * {@code true} if the runnable should be run in a separate thread,
+ * and {@code false} to run in the same thread
+ * @param cancelable
+ * {@code true} to enable the cancellation, and {@code false} to make the operation uncancellable
+ * @param runnable
+ * the runnable to run
+ *
+ * @exception InvocationTargetException
+ * wraps any exception or error which occurs
+ * while running the runnable
+ * @exception InterruptedException
+ * propagated by the context if the runnable
+ * acknowledges cancellation by throwing this exception. This should not be thrown
+ * if {@code cancelable} is {@code false}.
+ */
+ public static <V> V call(IRunnableContext context, boolean fork, boolean cancelable, IProgressCallable<V> callable) throws InvocationTargetException, InterruptedException {
+ class RunnableWrapper implements IRunnableWithProgress {
+ final IProgressCallable<V> delegate;
+
+ V result;
+
+ RunnableWrapper(IProgressCallable<V> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ result = delegate.call(monitor);
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException(e.getMessage());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ RunnableWrapper wrapper = new RunnableWrapper(callable);
+ context.run(fork, cancelable, wrapper);
+ return wrapper.result;
+ }
+
+ /**
+ * Obtains a simple executor that asynchronously executes at most one task on the default
+ * display thread. While any task is still pending execution on this executor,
+ * all others are silently discarded. This is useful for cases where, for example, UI
+ * refreshes are posted repeatedly from independent events that aren't aware of each other
+ * but where each refresh task would repeat the same work.
+ *
+ * @param display
+ * a display on which thread to execute tasks
+ *
+ * @return the executor
+ *
+ * @see #createAsyncOnceExecutor(Display)
+ */
+ public static Executor createAsyncOnceExecutor() {
+ return createAsyncOnceExecutor(Display.getDefault());
+ }
+
+ /**
+ * Obtains a simple executor that asynchronously executes at most one task on the given {@code display}'s thread. While any task is still pending execution on this executor,
+ * all others are silently discarded. This is useful for cases where, for example, UI
+ * refreshes are posted repeatedly from independent events that aren't aware of each other
+ * but where each refresh task would repeat the same work.
+ *
+ * @param display
+ * a display on which thread to execute tasks
+ *
+ * @return the executor
+ */
+ public static Executor createAsyncOnceExecutor(final Display display) {
+ return new Executor() {
+ private final AtomicBoolean pending = new AtomicBoolean();
+
+ @Override
+ public void execute(final Runnable task) {
+ if (pending.compareAndSet(false, true)) {
+ display.asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ pending.set(false);
+ task.run();
+ }
+ });
+ }
+ }
+ };
+ }
+
+ /**
+ * Obtains a tree iterator over all of the controls contained within a given {@code root} control, not including that {@code root}.
+ *
+ * @param root
+ * a control to iterate
+ * @return an unmodifiable iterator over all of its nested controls, which naturally will be empty if the {@code root} is not a {@link Composite}
+ */
+ public static TreeIterator<Control> allChildren(Control root) {
+ return new AbstractTreeIterator<Control>(root, false) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected Iterator<? extends Control> getChildren(Object object) {
+ return (object instanceof Composite) ? Iterators.forArray(((Composite) object).getChildren()) : Iterators.<Control> emptyIterator();
+ }
+ };
+ }
+
+ /**
+ * Obtains a tree iterator over all of the controls of a particular type contained within a given {@code root} control, not including that {@code root}.
+ *
+ * @param root
+ * a control to iterate
+ * @param type
+ * the type of children to include in the iteration
+ *
+ * @return an unmodifiable iterator over all of its nested controls, which naturally will be empty if the {@code root} is not a {@link Composite}
+ */
+ public static <C extends Control> TreeIterator<C> allChildren(Control root, final Class<C> type) {
+ return Iterators2.filter(allChildren(root), type);
+ }
+
+ //
+ // Nested types
+ //
+
+ private static abstract class UIExecutorService extends AbstractExecutorService implements IExecutorService {
+
+ private final Lock lock = new ReentrantLock();
+
+ private final Condition emptyCond = lock.newCondition();
+
+ private final Queue<RunnableWrapper> pending = new LinkedList<RunnableWrapper>();
+
+ private volatile boolean shutdown;
+
+ UIExecutorService() {
+ super();
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ if (isShutdown()) {
+ throw new RejectedExecutionException("Executor service is shut down"); //$NON-NLS-1$
+ }
+
+ asyncExec(enqueue(command));
+ }
+
+ @Override
+ public <V> V syncCall(Callable<V> callable) throws InterruptedException, ExecutionException {
+ class SyncResult implements Runnable {
+ V result;
+ ExecutionException fail;
+
+ @Override
+ public void run() {
+ try {
+ result = callable.call();
+ } catch (Exception e) {
+ fail = new ExecutionException(e);
+ fail.fillInStackTrace();
+ }
+ }
+ }
+
+ SyncResult result = new SyncResult();
+
+ syncExec(result);
+
+ if (result.fail != null) {
+ throw result.fail;
+ }
+
+ return result.result;
+ }
+
+ abstract void asyncExec(Runnable runnable);
+
+ @Override
+ public List<Runnable> shutdownNow() {
+ List<Runnable> result = new ArrayList<Runnable>();
+
+ shutdown();
+
+ for (Runnable dequeued = dequeue(); dequeued != null; dequeued = dequeue()) {
+ result.add(dequeued);
+ }
+
+ return result;
+ }
+
+ private RunnableWrapper enqueue(Runnable task) {
+ RunnableWrapper result = new RunnableWrapper(task);
+
+ lock.lock();
+ try {
+ boolean wasEmpty = pending.isEmpty();
+ pending.offer(result);
+ if (wasEmpty) {
+ // Now not empty
+ emptyCond.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return result;
+ }
+
+ private RunnableWrapper dequeue() {
+ RunnableWrapper result = null;
+
+ lock.lock();
+ try {
+ result = pending.poll();
+ if (result == null) {
+ // Now empty
+ emptyCond.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return result;
+ }
+
+ boolean dequeue(RunnableWrapper task) {
+ boolean result = false;
+
+ lock.lock();
+ try {
+ result = pending.remove(task);
+ if (result && pending.isEmpty()) {
+ // Now empty
+ emptyCond.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return result;
+ }
+
+ @Override
+ public void shutdown() {
+ shutdown = true;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ lock.lock();
+ try {
+ return isShutdown() && pending.isEmpty();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return shutdown;
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+ if (timeout < 0L) {
+ throw new IllegalArgumentException("negative timeout"); //$NON-NLS-1$
+ }
+
+ final Date deadline = (timeout == 0L) ? null : new Date(System.currentTimeMillis() + unit.toMillis(timeout));
+ boolean result = false;
+
+ lock.lock();
+ try {
+ boolean stillWaiting = true;
+ for (result = isTerminated(); !result && stillWaiting; result = isTerminated()) {
+ if (deadline == null) {
+ emptyCond.await();
+ } else {
+ stillWaiting = emptyCond.awaitUntil(deadline);
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return result;
+ }
+
+ @Override
+ public Future<?> submit(IProgressRunnable task) {
+ return submit(new IProgressCallable<Void>() {
+ @Override
+ public Void call(IProgressMonitor monitor) {
+ task.run(monitor);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void syncExec(IProgressRunnable task) throws InterruptedException, ExecutionException {
+ syncCall(new IProgressCallable<Void>() {
+ @Override
+ public Void call(IProgressMonitor monitor) {
+ task.run(monitor);
+ return null;
+ }
+ });
+ }
+
+ IProgressService getProgressService(IProgressCallable<?> callable) {
+ IProgressService result;
+
+ try {
+ ServicesRegistry registry = (callable instanceof IServiceRegistryProvider)
+ ? ((IServiceRegistryProvider) callable).getServiceRegistry()
+ : null;
+ IMultiDiagramEditor editor = ServiceUtils.getInstance().getService(
+ IMultiDiagramEditor.class, registry);
+ result = editor.getEditorSite().getService(IWorkbenchSiteProgressService.class);
+ } catch (ServiceException e) {
+ // Fine, there's no editor
+ result = PlatformUI.getWorkbench().getProgressService();
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ private class RunnableWrapper implements Runnable {
+
+ private final Runnable delegate;
+
+ RunnableWrapper(Runnable delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void run() {
+ // Don't run if I was cancelled by shutdown
+ if (dequeue(this)) {
+ delegate.run();
+ }
+ }
+ }
+ };
+
+ private static class DisplayExecutorService extends UIExecutorService {
+ private final Display display;
+
+ DisplayExecutorService(Display display) {
+ super();
+
+ this.display = display;
+ }
+
+ @Override
+ void asyncExec(Runnable runnable) {
+ display.asyncExec(runnable);
+ }
+
+ @Override
+ public void syncExec(Runnable task) {
+ display.syncExec(task);
+ }
+
+ @Override
+ public <V> Future<V> submit(IProgressCallable<V> callable) {
+ IProgressService service = getProgressService(callable);
+ IWorkbenchSiteProgressService wbService = (service instanceof IWorkbenchSiteProgressService) ? (IWorkbenchSiteProgressService) service : null;
+
+ FutureProgress<V> result = new FutureProgress<>(callable, wbService);
+
+ try {
+ service.run(true, true, result);
+ } catch (Exception e) {
+ // This shouldn't happen when running asynchronously
+ result.completeExceptionally(e);
+ }
+
+ return result;
+ }
+
+ @Override
+ public <V> V syncCall(IProgressCallable<V> callable) throws InterruptedException, ExecutionException {
+ IProgressService service = getProgressService(callable);
+ IWorkbenchSiteProgressService wbService = (service instanceof IWorkbenchSiteProgressService) ? (IWorkbenchSiteProgressService) service : null;
+
+ FutureProgress<V> result = new FutureProgress<>(callable, wbService);
+
+ try {
+ service.busyCursorWhile(result);
+ } catch (Exception e) {
+ result.completeExceptionally(e);
+ }
+
+ return result.get(); // It really should be completed, by now
+ }
+ }
+
+ private static class RealmExecutorService extends UIExecutorService {
+ private final Realm realm;
+
+ RealmExecutorService(Realm realm) {
+ super();
+
+ this.realm = realm;
+ }
+
+ @Override
+ void asyncExec(Runnable runnable) {
+ realm.asyncExec(runnable);
+ }
+
+ @Override
+ public void syncExec(Runnable task) {
+ realm.exec(task);
+ }
+
+ @Override
+ public <V> Future<V> submit(IProgressCallable<V> callable) {
+ // No place to report progress in this case
+ FutureTask<V> result = new FutureTask<V>(() -> callable.call(new NullProgressMonitor()));
+ asyncExec(result);
+ return result;
+ }
+
+ @Override
+ public <V> V syncCall(IProgressCallable<V> callable) throws InterruptedException, ExecutionException {
+ // No place to report progress in this case
+ FutureTask<V> result = new FutureTask<V>(() -> callable.call(new NullProgressMonitor()));
+ syncExec(result);
+ return result.get(); // It really should be completed, by now
+ }
+ }
+
+ private static class FutureProgress<V> extends CompletableFuture<V> implements IRunnableWithProgress {
+ private final IProgressCallable<V> delegate;
+ private final IWorkbenchSiteProgressService service;
+
+ private volatile IProgressMonitor monitor;
+
+ FutureProgress(IProgressCallable<V> delegate, IWorkbenchSiteProgressService service) {
+ super();
+
+ this.delegate = delegate;
+ this.service = service;
+ }
+
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ this.monitor = monitor;
+
+ if (service != null) {
+ service.incrementBusy();
+ }
+
+ try {
+ complete(delegate.call(monitor));
+ } finally {
+ this.monitor = null;
+
+ if (service != null) {
+ service.decrementBusy();
+ }
+ }
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException(e.getMessage());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ IProgressMonitor monitor = this.monitor;
+ if (monitor != null) {
+ monitor.setCanceled(true);
+ }
+
+ return super.cancel(mayInterruptIfRunning);
+ }
+
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/WorkbenchPartHelper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/WorkbenchPartHelper.java
new file mode 100644
index 00000000000..4ecdc94d48f
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/WorkbenchPartHelper.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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.ui.util;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ *
+ * a helper for the Eclipse workbench part
+ *
+ */
+public class WorkbenchPartHelper {
+
+ private WorkbenchPartHelper() {
+ // nothing to do
+ }
+
+ /**
+ *
+ * @return
+ * the current IWorkbenchPart or <code>null</code> if not found
+ */
+ public static final IWorkbenchPart getCurrentActiveWorkbenchPart() {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) {
+ final IWorkbenchWindow activeWorkbench = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbench != null) {
+ final IWorkbenchPage activePage = activeWorkbench.getActivePage();
+ if (activePage != null) {
+ return activePage.getActivePart();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @return
+ * the current IEditorPart or <code>null</code> if not found
+ */
+ public static final IEditorPart getCurrentActiveEditorPart() {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) {
+ final IWorkbenchWindow activeWorkbench = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbench != null) {
+ final IWorkbenchPage activePage = activeWorkbench.getActivePage();
+ if (activePage != null) {
+ return activePage.getActiveEditor();
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.classpath b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.project b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.project
new file mode 100644
index 00000000000..339688bbd54
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.infra.widgets.toolbox</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..b3aa6d60f94
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,291 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=260
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=260
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.ui.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..954281dbc31
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,68 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Papyrus
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Papyrus
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..1aea866730d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Export-Package: org.eclipse.papyrus.infra.widgets.toolbox,
+ org.eclipse.papyrus.infra.widgets.toolbox.dialog,
+ org.eclipse.papyrus.infra.widgets.toolbox.draw2d,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.builders,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.exception,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.popups,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.utils,
+ org.eclipse.papyrus.infra.widgets.toolbox.notification.view,
+ org.eclipse.papyrus.infra.widgets.toolbox.utils
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.ui.forms;bundle-version="3.5.100",
+ org.eclipse.draw2d;bundle-version="3.8.1",
+ org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.ui;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.tools;bundle-version="1.2.0";visibility:=reexport
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.2.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Localization: plugin
+Bundle-Activator: org.eclipse.papyrus.infra.widgets.toolbox.Activator
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.papyrus.infra.widgets.toolbox;singleton:=true
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/about.html b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/about.html
new file mode 100644
index 00000000000..d35d5aed64c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/build.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/build.properties
new file mode 100644
index 00000000000..a491a4cb7bd
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/build.properties
@@ -0,0 +1,7 @@
+#
+#Mon Sep 12 09:30:21 CEST 2011
+bin.includes=META-INF/,.,plugin.properties,plugin.xml,about.html,icons/,schema/
+output..=bin/
+src.includes=schema/,about.html,META-INF/,.,plugin.properties,plugin.xml,icons/
+source..=src/
+bin..=bin/
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/run.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/run.gif
new file mode 100644
index 00000000000..57f410224cf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/run.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/sample.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/sample.gif
new file mode 100644
index 00000000000..a32f4b1b572
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/icons/sample.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.properties
new file mode 100644
index 00000000000..aff1171d040
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.properties
@@ -0,0 +1,12 @@
+################################################################################
+# Copyright (c) 2008 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
+##################################################################################
+pluginName=Papyrus UI Toolbox
+providerName=Eclipse Modeling Project
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.xml
new file mode 100644
index 00000000000..d9b8f0fc162
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+
+<!--
+ ################################################################################
+# Copyright (c) 2008 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:
+# CEA LIST - initial API and implementation
+##################################################################################
+-->
+
+<plugin>
+ <extension-point id="papyrusNotificationBuilder" name="Papyrus Notification Builder" schema="schema/papyrusNotificationBuilder.exsd"/>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ category="org.eclipse.papyrus.views.category"
+ class="org.eclipse.papyrus.infra.widgets.toolbox.notification.view.PapyrusNotificationView"
+ icon="icons/sample.gif"
+ id="org.eclipse.papyrus.ui.toolbox.notification.view.PapyrusNotificationView"
+ name="Papyrus Notification">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.infra.widgets.toolbox.papyrusNotificationBuilder">
+ <BuilderInstance
+ builder="org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.PopupBuilder">
+ </BuilderInstance>
+ <BuilderInstance
+ builder="org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.ViewBuilder">
+ </BuilderInstance>
+ <BuilderInstance
+ builder="org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.AsyncNotifierBuilder">
+ </BuilderInstance>
+ </extension>
+</plugin>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/pom.xml
new file mode 100644
index 00000000000..ab60287d84d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.infra.widgets.toolbox</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/schema/papyrusNotificationBuilder.exsd b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/schema/papyrusNotificationBuilder.exsd
new file mode 100644
index 00000000000..977b7eb10be
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/schema/papyrusNotificationBuilder.exsd
@@ -0,0 +1,121 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.infra.widgets.toolbox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.infra.widgets.toolbox" id="papyrusNotificationBuilder" name="Papyrus Notification Builder"/>
+ </appInfo>
+ <documentation>
+ This extension point allows developers to define custom IBuilder instance to be managed by notification Builder.
+An IBuider has to define the methods accept and build.
+Take care to not always return true in the method accept to avoid intercepting all the notifications
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="BuilderInstance"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="BuilderInstance">
+ <complexType>
+ <attribute name="builder" type="string" use="required">
+ <annotation>
+ <documentation>
+ the builder instance. The implementation shall implement the methods to recognize and run a notification.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 0.7.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * ATOS ORIGIN - initial API and implementation
+ *******************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/Activator.java
new file mode 100644
index 00000000000..68a7cbf3ba1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/Activator.java
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * Copyright (c) 2008, 2016 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:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.infra.tools.spi.INotificationBuilderFactory;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * 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.toolbox";
+
+ // The shared instance
+ private static Activator plugin;
+
+ private ServiceRegistration<INotificationBuilderFactory> notificationBuilderReg;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ notificationBuilderReg = context.registerService(INotificationBuilderFactory.class, NotificationBuilder::new, null);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ notificationBuilderReg.unregister();
+ notificationBuilderReg = null;
+
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * This method returns an <code>org.eclipse.swt.graphics.Image</code> identified by its pluginId and iconPath.<BR>
+ *
+ * By default, it returns a default image. This image is the image placed in
+ * the directory <em>resources/icons/default.gif</em>
+ *
+ * @param pluginId
+ * id of plugin
+ * @param iconpPath
+ * the path of the icon image relative to the plugin
+ * @return the Image
+ */
+ public static Image getImage(String iconPath, String defaultPlugin) {
+ // see if the path is using platform:/... to get icon in the fragment, if it is in a fragment
+ String key = defaultPlugin + iconPath;
+ ImageRegistry registry = getDefault().getImageRegistry();
+ Image image = registry.get(key);
+
+ if (image == null) {
+
+ ImageDescriptor desc = AbstractUIPlugin.imageDescriptorFromPlugin(defaultPlugin, iconPath);
+ registry.put(key, desc);
+ image = registry.get(key);
+
+ }
+ return image;
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/SwtUtil.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/SwtUtil.java
new file mode 100644
index 00000000000..f7ea106c770
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/SwtUtil.java
@@ -0,0 +1,167 @@
+/*****************************************************************************
+ * Copyright (c) Eclipse.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mik Kersten
+ * Steffen Pingel
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox;
+
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * @author Mik Kersten
+ * @author Steffen Pingel
+ */
+public class SwtUtil {
+
+ public static final long FADE_RESCHEDULE_DELAY = 80;
+
+ public static final int FADE_IN_INCREMENT = 15;
+
+ public static final int FADE_OUT_INCREMENT = -20;
+
+ public static void collectItemData(TreeItem[] items, Set<Object> allVisible) {
+ for (TreeItem item : items) {
+ allVisible.add(item.getData());
+ collectItemData(item.getItems(), allVisible);
+ }
+ }
+
+ public static FadeJob fastFadeIn(Shell shell, SwtUtil.IFadeListener listener) {
+ return new FadeJob(shell, 2 * FADE_IN_INCREMENT, FADE_RESCHEDULE_DELAY, listener);
+ }
+
+ public static FadeJob fadeIn(Shell shell, SwtUtil.IFadeListener listener) {
+ return new FadeJob(shell, FADE_IN_INCREMENT, FADE_RESCHEDULE_DELAY, listener);
+ }
+
+ public static FadeJob fadeOut(Shell shell, SwtUtil.IFadeListener listener) {
+ return new FadeJob(shell, FADE_OUT_INCREMENT, FADE_RESCHEDULE_DELAY, listener);
+ }
+
+ public static class FadeJob extends Job {
+
+ private final Shell shell;
+
+ private final int increment;
+
+ private volatile boolean stopped;
+
+ private volatile int currentAlpha;
+
+ private final long delay;
+
+ private final IFadeListener fadeListener;
+
+ public FadeJob(Shell shell, int increment, long delay, IFadeListener fadeListener) {
+ super("Fading");
+ if (increment < -255 || increment == 0 || increment > 255) {
+ throw new IllegalArgumentException("-255 <= increment <= 255 && increment != 0"); //$NON-NLS-1$
+ }
+ if (delay < 1) {
+ throw new IllegalArgumentException("delay must be > 0"); //$NON-NLS-1$
+ }
+ this.currentAlpha = shell.getAlpha();
+ this.shell = shell;
+ this.increment = increment;
+ this.delay = delay;
+ this.fadeListener = fadeListener;
+
+ setSystem(true);
+ schedule(delay);
+ }
+
+ @Override
+ protected void canceling() {
+ stopped = true;
+ }
+
+ private void reschedule() {
+ if (stopped) {
+ return;
+ }
+ schedule(delay);
+ }
+
+ public void cancelAndWait(final boolean setAlpha) {
+ if (stopped) {
+ return;
+ }
+ cancel();
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ if (setAlpha) {
+ shell.setAlpha(getLastAlpha());
+ }
+ }
+ });
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ if (stopped) {
+ return Status.OK_STATUS;
+ }
+
+ currentAlpha += increment;
+ if (currentAlpha <= 0) {
+ currentAlpha = 0;
+ } else if (currentAlpha >= 255) {
+ currentAlpha = 255;
+ }
+
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ if (stopped) {
+ return;
+ }
+
+ if (shell.isDisposed()) {
+ stopped = true;
+ return;
+ }
+
+ shell.setAlpha(currentAlpha);
+
+ if (fadeListener != null) {
+ fadeListener.faded(shell, currentAlpha);
+ }
+ }
+ });
+
+ if (currentAlpha == 0 || currentAlpha == 255) {
+ stopped = true;
+ }
+
+ reschedule();
+ return Status.OK_STATUS;
+ }
+
+ private int getLastAlpha() {
+ return (increment < 0) ? 0 : 255;
+ }
+
+ }
+
+ public static interface IFadeListener {
+
+ public void faded(Shell shell, int alpha);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/dialog/InformationDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/dialog/InformationDialog.java
new file mode 100644
index 00000000000..78a2033b03d
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/dialog/InformationDialog.java
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * Copyright (c) 2010 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.dialog;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A JFace dialog used to show information to the end user.<br>
+ * This dialog is able to store the user choice into a preference store.<br>
+ *
+ */
+public class InformationDialog extends MessageDialog {
+
+ private IPreferenceStore ps;
+
+ private String preference;
+
+ private Button rememberChoice;
+
+ /**
+ * The Constructor.
+ *
+ * @param parentShell
+ * the parent shell
+ * @param dialogTitle
+ * the dialog title
+ * @param message
+ * the message
+ * @param pso
+ * the preference store
+ * @param preference
+ * the preference
+ */
+ public InformationDialog(Shell parentShell, String dialogTitle,
+ String message, IPreferenceStore ps, String preference) {
+ this(parentShell, dialogTitle, message, ps, preference, SWT.OK,
+ MessageDialog.INFORMATION,
+ new String[] { IDialogConstants.OK_LABEL });
+ }
+
+ /**
+ * The Constructor.
+ *
+ * @param parentShell
+ * the parent shell
+ * @param dialogTitle
+ * the dialog title
+ * @param message
+ * the message
+ * @param ps
+ * the ps the preference store
+ * @param preference
+ * the preference string to store the choice
+ * @param style
+ * the style for buttons : SWT.OK, SWT.YES
+ * @param messageDialogType
+ * : MessageDialog.INFORMATION, MessageDialog.WARNING
+ * @param labels
+ * the labels, for example IDialogConstants.OK_LABEL
+ */
+ public InformationDialog(Shell parentShell, String dialogTitle,
+ String message, IPreferenceStore ps, String preference, int style,
+ int messageDialogType, String[] labels) {
+ super(parentShell, dialogTitle, null, message, messageDialogType,
+ labels, style);
+ this.ps = ps;
+ this.preference = preference;
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.MessageDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite container = (Composite) super.createDialogArea(parent);
+
+ if (ps != null && preference != null && preference.length() > 0) {
+ rememberChoice = new Button(container, SWT.CHECK);
+ rememberChoice.setText("Do not show again");
+ }
+ return container;
+ }
+
+ /**
+ * @see org.eclipse.jface.window.Window#open() return Window.OK if it's
+ * valid
+ */
+ @Override
+ public int open() {
+ // Do not open the dialog if the preference is true
+ if (ps != null && preference != null && preference.length() > 0) {
+ if (ps.getBoolean(preference)) {
+ return Window.OK;
+ }
+ }
+ return super.open();
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+ */
+ @Override
+ protected void buttonPressed(int buttonId) {
+ // OK pressed
+ if (buttonId == Window.OK && rememberChoice != null && rememberChoice.getSelection()) {
+ if (ps != null && preference != null && preference.length() > 0) {
+ // Store the preference
+ ps.setValue(preference, true);
+ }
+ }
+ super.buttonPressed(buttonId);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/draw2d/ManuallyDrawnShortcutDecorationFigure.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/draw2d/ManuallyDrawnShortcutDecorationFigure.java
new file mode 100644
index 00000000000..09711f396b1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/draw2d/ManuallyDrawnShortcutDecorationFigure.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Conselleria de Infraestructuras y Transporte,
+ * Generalitat de la Comunitat Valenciana .
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Francisco Javier Cano Muñoz (Prodevelop) - initial API implementation
+ *
+ ******************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.draw2d;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Polygon;
+import org.eclipse.draw2d.RectangleFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.swt.graphics.Color;
+
+public class ManuallyDrawnShortcutDecorationFigure extends RectangleFigure {
+
+ private RectangleFigure border = null;
+
+ public ManuallyDrawnShortcutDecorationFigure() {
+ setOpaque(true);
+ setOutline(false);
+
+ setSize(10, 10);
+ setPreferredSize(10, 10);
+
+ border = new RectangleFigure();
+ border.setForegroundColor(ColorConstants.black);
+ border.setBackgroundColor(ColorConstants.white);
+ border.setSize(10, 10);
+ border.setLocation(new Point(0, 0));
+ this.add(border);
+
+ Polygon arrow = new Polygon();
+ arrow.setLocation(new Point(0, 0));
+ arrow.setForegroundColor(ColorConstants.black);
+ arrow.setBackgroundColor(ColorConstants.black);
+ arrow.setFill(true);
+
+ arrow.addPoint(new Point(7, 2));
+ arrow.addPoint(new Point(7, 5));
+ arrow.addPoint(new Point(7, 4));
+ arrow.addPoint(new Point(5, 4));
+ arrow.addPoint(new Point(5, 5));
+ arrow.addPoint(new Point(3, 7));
+ arrow.addPoint(new Point(4, 8));
+ arrow.addPoint(new Point(3, 7));
+ arrow.addPoint(new Point(3, 5));
+ arrow.addPoint(new Point(5, 3));
+ arrow.addPoint(new Point(5, 3));
+ arrow.addPoint(new Point(4, 2));
+ arrow.addPoint(new Point(7, 2));
+
+ this.add(arrow);
+ }
+
+ @Override
+ public void setBackgroundColor(Color backgroundColor) {
+ border.setBackgroundColor(backgroundColor);
+ }
+
+ @Override
+ protected boolean useLocalCoordinates() {
+ return true;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/IBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/IBuilder.java
new file mode 100644
index 00000000000..80862cde3ce
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/IBuilder.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.PropertyWrapper;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * An IBuilder helps the notification builder to create a notification
+ *
+ * @author tfaure
+ *
+ */
+public interface IBuilder {
+
+ /**
+ * This method displays the notification message
+ *
+ * @param wrapper
+ * , a wrapper containing all the options to create the message
+ * @param toolkit
+ * , the toolkit for form creation
+ */
+ INotification build(PropertyWrapper wrapper, FormToolkit toolkit);
+
+ /**
+ * Determines if the IBuilder can manage the parameter with its value
+ *
+ * @param parameterName
+ * , the name of the parameter (see constants in {@link NotificationBuilder} calss
+ * @param value
+ * , the value of the corresponding parameter
+ * @return true if the parameterName or the value can be managed by the builder
+ */
+ boolean accept(String parameterName, Object value);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICallBack.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICallBack.java
new file mode 100644
index 00000000000..d8edf6394e3
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICallBack.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+
+/**
+ * A class providing services to be called back
+ *
+ * @author tristan faure
+ *
+ */
+public interface ICallBack {
+
+ /**
+ * This method is called by the callee
+ *
+ * @param element
+ */
+ void callBack(Object element);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICompositeCreator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICompositeCreator.java
new file mode 100644
index 00000000000..3c0e1cf45ce
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/ICompositeCreator.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * A composite creator can create a specific composite in the notification
+ *
+ * @author tfaure
+ */
+public interface ICompositeCreator {
+
+ /**
+ * Create the composite in the parent using the toolkit
+ *
+ * @param parent
+ * , the parent of the composite
+ * @param toolkit
+ * , the toolkit to use
+ * @return the composite created
+ */
+ Composite createComposite(Composite parent, FormToolkit toolkit);
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/INotification.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/INotification.java
new file mode 100644
index 00000000000..80082dee0da
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/INotification.java
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 ATOS ORIGIN, 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:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+
+/**
+ * The Interface INotification.
+ * offers some services for a notification
+ */
+public interface INotification extends org.eclipse.papyrus.infra.tools.notify.INotification {
+ // No additional API
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/NotificationRunnable.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/NotificationRunnable.java
new file mode 100644
index 00000000000..6cbec8b5325
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/NotificationRunnable.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext;
+
+/**
+ * a runnable
+ *
+ */
+public interface NotificationRunnable {
+
+ /**
+ * Run the runnable
+ *
+ * @param context
+ * , used to fill properties, can contain data
+ */
+ void run(IContext context);
+
+ /**
+ * The label of the runnable
+ *
+ * @return the label
+ */
+ String getLabel();
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/PapyrusToolkit.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/PapyrusToolkit.java
new file mode 100644
index 00000000000..ea919c936f5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/PapyrusToolkit.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+
+
+/**
+ * This class allows specific toolkit for component creation
+ *
+ * @author tfaure
+ *
+ */
+public class PapyrusToolkit extends FormToolkit {
+
+ public static int DEFAULT_STYLE = -1;
+
+ /**
+ * The unique instance of the papyrus toolkit
+ */
+ public static PapyrusToolkit INSTANCE = new PapyrusToolkit(Display.getDefault());
+
+ private PapyrusToolkit(Display display) {
+ super(display);
+ }
+
+ @Override
+ public Section createSection(Composite parent, int sectionStyle) {
+ if (sectionStyle == DEFAULT_STYLE) {
+ return super.createSection(parent, ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
+ }
+ return super.createSection(parent, sectionStyle);
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/Type.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/Type.java
new file mode 100644
index 00000000000..90dd825d5a7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/Type.java
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification;
+
+
+/**
+ * The different types of Notifications <li>INFO</i> <li>WARNING</i> <li>ERROR</i> <li>QUESTION</i>
+ *
+ * @author tristan faure
+ *
+ */
+public enum Type {
+ INFO, WARNING, ERROR, QUESTION
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/AsyncNotifierBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/AsyncNotifierBuilder.java
new file mode 100644
index 00000000000..4f67eeba1a0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/AsyncNotifierBuilder.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.AsyncNotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.ImagePapyrusAsyncNotificationPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusAsyncNotificationPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * A Builder able to create {@link PapyrusAsyncNotificationPopup} instances
+ *
+ * @author tristan faure
+ *
+ */
+public class AsyncNotifierBuilder implements IBuilder {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#build(org.eclipse.papyrus.infra.widgets.toolbox.notification.PropertyWrapper,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ */
+ public INotification build(PropertyWrapper wrapper, final FormToolkit toolkit) {
+ PapyrusAsyncNotificationPopup popup = null;
+ if (wrapper.getComposite() != null) {
+ final ICompositeCreator composite = wrapper.getComposite();
+ // use the creator to a notification with image
+ if (wrapper.getType() != null) {
+ popup = new ImagePapyrusAsyncNotificationPopup(Display.getDefault(), toolkit, wrapper.getType()) {
+
+ @Override
+ protected void doCreateClient(Composite parent) {
+ PapyrusControlsFactory.createCompositeWithType(getShell(), null, parent, type, image, text, false, composite, context);
+ }
+
+ };
+ } else {
+ // use the creator to a notification without image
+ popup = new PapyrusAsyncNotificationPopup(Display.getDefault(), toolkit) {
+
+ @Override
+ protected void doCreateClient(Composite parent) {
+ Composite compo = composite.createComposite(parent, toolkit);
+ setCompositeCreated(compo);
+ }
+ };
+ }
+ } else {
+ if (wrapper.getType() != null) {
+ popup = new ImagePapyrusAsyncNotificationPopup(Display.getDefault(), toolkit, wrapper.getType());
+ } else {
+ popup = new PapyrusAsyncNotificationPopup(Display.getDefault(), toolkit);
+ }
+ String text = wrapper.getMessage();
+ if (text == null) {
+ text = "no text";
+ }
+ popup.setText(text);
+ }
+ if (wrapper.getDelay() != null) {
+ popup.setDelayClose(wrapper.getDelay());
+ }
+ if (wrapper.getActions() != null) {
+ popup.addAllRunnable(wrapper.getActions());
+ }
+ popup.setTitle(wrapper.getTitle() == null ? "Papyrus" : wrapper.getTitle());
+ AsyncNotification notification = new AsyncNotification(popup);
+ popup.setINotification(notification);
+ popup.open();
+ return notification;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#accept(java.lang.String, java.lang.Object)
+ */
+ public boolean accept(String parameterName, Object value) {
+ if (NotificationBuilder.ASYNCHRONOUS.equals(parameterName)) {
+ return value instanceof Boolean && ((Boolean) value);
+ }
+ if (NotificationBuilder.TEMPORARY.equals(parameterName)) {
+ return value instanceof Boolean && (Boolean) value;
+ }
+ if (NotificationBuilder.MESSAGE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.COMPOSITE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.ACTION.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.DELAY.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.IMAGE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.TYPE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.HTML.equals(parameterName)) {
+ return value instanceof Boolean && !(Boolean) value;
+ }
+ if (NotificationBuilder.TITLE.equals(parameterName)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/CombinedPopupAndViewBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/CombinedPopupAndViewBuilder.java
new file mode 100644
index 00000000000..f6621f36983
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/CombinedPopupAndViewBuilder.java
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * 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:
+ *
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import java.util.HashSet;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.AsyncNotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.ImagePapyrusAsyncNotificationPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusAsyncNotificationPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.AbstractInsideComposite;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.PapyrusNotificationView;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.ViewNotification;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * <pre>
+ * This builder creates notification both in a temporary pop-up and in Papyrus notification view.
+ * It is not supposed to be registered in extension point as its implementation can possibly interfere with existing ones
+ * ({@link ViewBuilder}, {@link AsyncNotifierBuilder}).
+ *
+ * It is assumed the title, message and type are set before use.
+ *
+ * Usage example : new NotificationBuilder().setBuilderClass(MyBuilder.class).setType(type).setTitle(title).setMessage(message).run();
+ *
+ * The expected behavior is the following :
+ * - if the notification view is not active, a popup is shown and a notification is added in the view.
+ * - if the notification view is active the notification is added in the view (no popup).
+ * - if the notification view is not opened, it get created but do not get the focus so that the active view does not switch automatically.
+ * </pre>
+ */
+public class CombinedPopupAndViewBuilder implements IBuilder {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#build(org.eclipse.papyrus.infra.widgets.toolbox.notification.PropertyWrapper,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ */
+ public INotification build(PropertyWrapper wrapper, FormToolkit toolkit) {
+
+ // Find PapyrusNotificationView or create it but do not give it the focus, let the user decide when to consult these
+ // informations.
+ PapyrusNotificationView notificationView = (PapyrusNotificationView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(PapyrusNotificationView.ID);
+ if (notificationView == null) {
+ try {
+ notificationView = (PapyrusNotificationView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(PapyrusNotificationView.ID, null, IWorkbenchPage.VIEW_CREATE);
+ } catch (PartInitException e) {
+ // log error - unable to create notification view
+ return null;
+ }
+ }
+
+ // If the Notification view is not visible show temporary notification
+ if ((notificationView != null) && !(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().isPartVisible(notificationView))) {
+ createNotificationPopup(wrapper, toolkit);
+ }
+
+ // In any case, log the notification in the PapyrusNotificationView so that the user can consult this later.
+ return createNotificationLog(notificationView, wrapper, toolkit);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#accept(java.lang.String, java.lang.Object)
+ */
+ public boolean accept(String parameterName, Object value) {
+ return true;
+ }
+
+ /**
+ * This method creates the notification as a temporary popup.
+ *
+ * @param wrapper
+ * the notification property wrapper.
+ * @param toolkit
+ * the form toolkit.
+ * @return the notification.
+ */
+ private INotification createNotificationPopup(final PropertyWrapper wrapper, FormToolkit toolkit) {
+
+ PapyrusAsyncNotificationPopup popup = new ImagePapyrusAsyncNotificationPopup(Display.getDefault(), toolkit, wrapper.getType());
+ popup.setTitle(wrapper.getTitle());
+ popup.setText(wrapper.getMessage());
+ popup.addAllRunnable(wrapper.getActions() == null ? new HashSet<NotificationRunnable>() : wrapper.getActions());
+
+ AsyncNotification notification = new AsyncNotification(popup);
+ popup.setINotification(notification);
+
+ popup.open();
+
+ return notification;
+ }
+
+ /**
+ * This method add notifications in the notification view.
+ *
+ * @param notificationView
+ * the notification view.
+ * @param wrapper
+ * the notification property wrapper.
+ * @param toolkit
+ * the form toolkit.
+ * @return the notification.
+ */
+ private INotification createNotificationLog(PapyrusNotificationView notificationView, final PropertyWrapper wrapper, final FormToolkit toolkit) {
+
+ ICompositeCreator compositeCreator = wrapper.getComposite();
+ if (compositeCreator == null) {
+
+ compositeCreator = new ICompositeCreator() {
+
+ public Composite createComposite(Composite parent, FormToolkit toolkit) {
+ return PapyrusControlsFactory.createCompositeWithType(Display.getDefault().getActiveShell(), toolkit, parent, wrapper.getType(), wrapper.getImage(), wrapper.getMessage(), false);
+ }
+
+ };
+ }
+
+ AbstractInsideComposite compositeNotification = notificationView.setComposite(compositeCreator, wrapper.getTitle(), wrapper.getActions());
+ ViewNotification notification = new ViewNotification(compositeNotification);
+ compositeNotification.setINotification(notification);
+
+ return notification;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/IContext.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/IContext.java
new file mode 100644
index 00000000000..8c40affaa39
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/IContext.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 ATOS ORIGIN, 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:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * The Class Context.
+ */
+public interface IContext extends org.eclipse.papyrus.infra.tools.notify.IContext {
+
+ class Context implements IContext {
+
+ private Map<String, Object> objects = new HashMap<String, Object>();;
+
+ @Override
+ public void put(String s, Object o) {
+ objects.put(s, o);
+ }
+
+ @Override
+ public Object get(String s) {
+ return objects.get(s);
+ }
+
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/NotificationBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/NotificationBuilder.java
new file mode 100644
index 00000000000..db46f76958c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/NotificationBuilder.java
@@ -0,0 +1,546 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2016 ATOS ORIGIN, 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:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ * Christian W. Damus - bug 485220
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.infra.tools.notify.INotificationBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.PapyrusToolkit;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.popups.PopupNotification;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * <p>
+ * A class creating a notification.
+ * The {@link #run()} method launches the message according to the value of the attributes.
+ * </p>
+ * <p>
+ * Consider using the headless-compatible {@link org.eclipse.papyrus.infra.tools.notify.NotificationBuilder API}
+ * if you don't need to specify an {@linkplain #setImage(Image) image} or a
+ * {@linkplain #setComposite(ICompositeCreator) composite} for your notification.
+ *
+ * @author tristan faure
+ *
+ */
+public class NotificationBuilder implements INotificationBuilder {
+
+ private FormToolkit toolkit = PapyrusToolkit.INSTANCE;
+
+ /** The parameters of the notification with the corresponding values */
+ protected Map<String, Object> parameters = new HashMap<String, Object>();
+
+ /** a composite creator for the element */
+ static String COMPOSITE = "composite";
+
+ /** an image displayed generally at the left of the notification */
+ static String IMAGE = "image";
+
+ /** The builders creating the notification */
+ protected static Map<Class<? extends IBuilder>, IBuilder> builders = getBuilders();
+
+ /**
+ * Determine a specific builder class, if it is filled, it is forced to it
+ */
+ protected Class<? extends IBuilder> builderClass;
+
+
+ /**
+ * Returns the ibuilders able to create notifications
+ *
+ * @return the list of {@link IBuilder}
+ */
+ private static Map<Class<? extends IBuilder>, IBuilder> getBuilders() {
+ Map<Class<? extends IBuilder>, IBuilder> result = new HashMap<Class<? extends IBuilder>, IBuilder>();
+ IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.widgets.toolbox.papyrusNotificationBuilder");
+ for (IConfigurationElement e : elements) {
+ IBuilder instance;
+ try {
+ instance = (IBuilder) e.createExecutableExtension("builder");
+ result.put(instance.getClass(), instance);
+ } catch (CoreException e1) {
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set a message for the notification
+ *
+ * @param message
+ * , the message to display
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setMessage(String message) {
+ parameters.put(MESSAGE, message);
+ return this;
+ }
+
+ /**
+ * Determines if the notification is asynchronous (don't force the user to read the notification immediately)
+ *
+ * @param asynchronous
+ * , true if it asynchronous
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setAsynchronous(boolean asynchronous) {
+ parameters.put(ASYNCHRONOUS, asynchronous);
+ return this;
+ }
+
+ /**
+ * Set a default action for the notification
+ *
+ * @param runnable
+ * , a runnable triggered when default action of the notification is selected
+ * The first action added is the default One
+ * @return this
+ */
+ @SuppressWarnings("unchecked")
+ public NotificationBuilder addAction(NotificationRunnable runnable) {
+ Collection<NotificationRunnable> runnables = (Collection<NotificationRunnable>) parameters.get(ACTION);
+ if (runnables == null) {
+ runnables = new LinkedList<NotificationRunnable>();
+ parameters.put(ACTION, runnables);
+ }
+ runnables.add(runnable);
+ return this;
+ }
+
+ @Override
+ public NotificationBuilder addAction(final org.eclipse.papyrus.infra.tools.notify.NotificationRunnable runnable) {
+ return addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ runnable.run(context);
+ }
+
+ @Override
+ public String getLabel() {
+ return runnable.getLabel();
+ }
+ });
+ }
+
+ /**
+ * Set a composite creator, able to fill a notification
+ *
+ * @param creator
+ * , the composite creator
+ * @return this
+ */
+ public NotificationBuilder setComposite(ICompositeCreator creator) {
+ parameters.put(COMPOSITE, creator);
+ return this;
+ }
+
+ /**
+ * Set a delay if the notification is temporary
+ *
+ * @param delayMs
+ * , the delay in ms for visibility
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setDelay(long delayMs) {
+ parameters.put(DELAY, delayMs);
+ return this;
+ }
+
+ /**
+ * Set true if the notification is temporary
+ *
+ * @param temporary
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setTemporary(boolean temporary) {
+ parameters.put(TEMPORARY, temporary);
+ return this;
+ }
+
+ /**
+ * Set a title for the notification
+ *
+ * @param title
+ * , the title
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setTitle(String title) {
+ parameters.put(TITLE, title);
+ return this;
+ }
+
+ /**
+ * Set if the notification has to understand HTML
+ *
+ * @param useHTML
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setHTML(boolean useHTML) {
+ parameters.put(HTML, useHTML);
+ return this;
+ }
+
+ /**
+ * Set the type of the notification according to {@link Type}
+ *
+ * @param type
+ * , the desired type
+ * @return this
+ */
+ public NotificationBuilder setType(Type type) {
+ parameters.put(TYPE, type);
+ return this;
+ }
+
+ @Override
+ public NotificationBuilder setType(org.eclipse.papyrus.infra.tools.notify.Type type) {
+ return setType(Type.valueOf(type.name()));
+ }
+
+ /**
+ * Set an image for the notification
+ *
+ * @param image
+ * , the desired image
+ * @return this
+ */
+ public NotificationBuilder setImage(Image image) {
+ parameters.put(IMAGE, image);
+ return this;
+ }
+
+ /**
+ * Force a builder class
+ *
+ * @param builderClass
+ * , a class which inherits from {@link IBuilder}
+ * @return this
+ */
+ public NotificationBuilder setBuilderClass(Class<? extends IBuilder> builderClass) {
+ this.builderClass = builderClass;
+ return this;
+ }
+
+ /**
+ * Allows the developer to use a specific parameter
+ *
+ * @param name
+ * , the key of the parameter
+ * @param value
+ * , the value
+ * @return this
+ */
+ @Override
+ public NotificationBuilder setParameter(String name, Object value) {
+ if (TYPE.equals(name)) {
+ if (value instanceof org.eclipse.papyrus.infra.tools.notify.Type) {
+ value = Type.valueOf(((org.eclipse.papyrus.infra.tools.notify.Type) value).name());
+ }
+ }
+
+ parameters.put(name, value);
+ return this;
+ }
+
+ /**
+ * Creates a notification according to different parameters
+ */
+ @Override
+ public INotification run() {
+ Set<IBuilder> copy = null;
+ if (builderClass != null) {
+ copy = new HashSet<IBuilder>();
+ try {
+ copy.add(builderClass.newInstance());
+ } catch (InstantiationException e) {
+ } catch (IllegalAccessException e) {
+ }
+ } else {
+ copy = new HashSet<IBuilder>(builders.values());
+ }
+ for (Iterator<IBuilder> i = copy.iterator(); i.hasNext();) {
+ IBuilder b = i.next();
+ for (String string : parameters.keySet()) {
+ if (!b.accept(string, parameters.get(string))) {
+ i.remove();
+ break;
+ }
+ }
+ }
+ INotification result = null;
+ PropertyWrapper wrapper = new PropertyWrapper(parameters);
+ if (copy.size() >= 1) {
+ result = copy.iterator().next().build(wrapper, toolkit);
+ // default case : the popup
+ } else if (copy.isEmpty()) {
+ result = builders.get(PopupBuilder.class).build(wrapper, toolkit);
+ }
+ return result;
+ }
+
+ /**
+ * Creates a notification builder already configured to display an information builder
+ *
+ * @return a notification builder
+ */
+ public static NotificationBuilder createInformationBuilder() {
+ NotificationBuilder builder = new NotificationBuilder();
+ return builder;
+ }
+
+ /**
+ * Creates a notification builder already configured to display an asynchronous popup
+ *
+ * @param text
+ * , the text to display
+ * @return a notification builder
+ */
+ public static NotificationBuilder createAsyncPopup(String text) {
+ return new NotificationBuilder().setAsynchronous(true).setTemporary(true).setMessage(text).setDelay(2000);
+ }
+
+ /**
+ * Creates a notification builder already configured to display an asynchronous popup with a specified title
+ *
+ * @param text
+ * , the text to display
+ * @param title
+ * , the title of the popup
+ * @return a notification builder
+ */
+ public static NotificationBuilder createAsyncPopup(String title, String text) {
+ return new NotificationBuilder().setAsynchronous(true).setTemporary(true).setMessage(text).setTitle(title).setDelay(2000);
+ }
+
+ /**
+ * Creates a notification builder already configured to display an information popup
+ *
+ * @param text
+ * , the text to display
+ * @return a notification builder
+ */
+ public static NotificationBuilder createInfoPopup(String text) {
+ return new NotificationBuilder().setAsynchronous(false).setTemporary(false).setMessage(text).setType(Type.INFO);
+ }
+
+ /**
+ * Creates a notification builder already configured to display an warning popup
+ *
+ * @param text
+ * , the text to display
+ * @return a notification builder
+ */
+ public static NotificationBuilder createWarningPopup(String text) {
+ return new NotificationBuilder().setAsynchronous(false).setTemporary(false).setMessage(text).setType(Type.WARNING);
+ }
+
+ /**
+ * Creates a notification builder already configured to display a popup with question icon
+ *
+ * @param text
+ * , the text to display
+ * @return a notification builder
+ */
+ public static NotificationBuilder createQuestionPopup(String text) {
+ return new NotificationBuilder().setAsynchronous(false).setTemporary(false).setMessage(text).setType(Type.QUESTION);
+ }
+
+ /**
+ * Creates a notification builder already configured to display a popup with error icon
+ *
+ * @param text
+ * , the text to display
+ * @return a notification builder
+ */
+ public static NotificationBuilder createErrorPopup(String text) {
+ return new NotificationBuilder().setAsynchronous(false).setTemporary(false).setMessage(text).setType(Type.ERROR);
+ }
+
+ /**
+ * Creates a notification builder already configured to display a yes no question
+ *
+ * @param yes
+ * , the action to launch if yes is selected
+ * @param no
+ * , the action to launch if no is selected
+ * @return a notification builder
+ */
+ public static NotificationBuilder createYesNo(String message, final Runnable yes, final Runnable no) {
+ return new NotificationBuilder().setType(Type.QUESTION).setAsynchronous(false).setTemporary(false).setMessage(message).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ if (yes != null) {
+ context.put(IContext.ACTION_ID, SWT.YES);
+ yes.run();
+ }
+ }
+
+ @Override
+ public String getLabel() {
+ return "Yes";
+ }
+ }).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ if (no != null) {
+ context.put(IContext.ACTION_ID, SWT.NO);
+ no.run();
+ }
+ }
+
+ @Override
+ public String getLabel() {
+ return "No";
+ }
+ });
+ }
+
+ /**
+ * Creates a notification builder already configured to display a yes no question, no runnables are necesary as the user just want the
+ * PopupNotification result
+ * This NotificationRunnable is not intended to be changed to an asynchronous notification for example
+ * When the run method is called use getRsult method in {@link PopupNotification} and test if the value is SWT.YES or SWT.NO
+ *
+ * @param message
+ * , the message to display
+ *
+ * @return a notification builder
+ */
+ public static NotificationBuilder createYesNo(String message) {
+ return new NotificationBuilder().setType(Type.QUESTION).setAsynchronous(false).setTemporary(false).setMessage(message).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ context.put(IContext.ACTION_ID, SWT.YES);
+ }
+
+ @Override
+ public String getLabel() {
+ return "Yes";
+ }
+ }).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ context.put(IContext.ACTION_ID, SWT.NO);
+ }
+
+ @Override
+ public String getLabel() {
+ return "No";
+ }
+ });
+ }
+
+ /**
+ * Creates a notification builder already configured to display a yes no question
+ *
+ * @param yes
+ * , the action to launch if yes is selected
+ * @param no
+ * , the action to launch if no is selected
+ * @return a notification builder
+ */
+ public static NotificationBuilder createYesNo(String message, final NotificationRunnable yes, final NotificationRunnable no) {
+ return new NotificationBuilder().setType(Type.QUESTION).setAsynchronous(false).setTemporary(false).setMessage(message).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ if (yes != null) {
+ context.put(IContext.ACTION_ID, SWT.YES);
+ yes.run(context);
+ }
+ }
+
+ @Override
+ public String getLabel() {
+ return "Yes";
+ }
+ }).addAction(new NotificationRunnable() {
+
+ @Override
+ public void run(IContext context) {
+ if (no != null) {
+ context.put(IContext.ACTION_ID, SWT.NO);
+ no.run(context);
+ }
+ }
+
+ @Override
+ public String getLabel() {
+ return "No";
+ }
+ });
+ }
+
+ /**
+ * Return the system image according to the imageID
+ *
+ * @param imageID
+ * @param shell
+ * @return
+ */
+ public static Image getSWTImage(final int imageID, Shell shell) {
+ final Display display;
+ if (shell == null || shell.isDisposed()) {
+ display = Display.getCurrent();
+ // The dialog should be always instantiated in UI thread.
+ // However it was possible to instantiate it in other threads
+ // (the code worked in most cases) so the assertion covers
+ // only the failing scenario. See bug 107082 for details.
+ Assert.isNotNull(display, "The dialog should be created in UI thread"); //$NON-NLS-1$
+ } else {
+ display = shell.getDisplay();
+ }
+
+ final Image[] image = new Image[1];
+ display.syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ image[0] = display.getSystemImage(imageID);
+ }
+ });
+
+ return image[0];
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PopupBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PopupBuilder.java
new file mode 100644
index 00000000000..b2dea10ae00
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PopupBuilder.java
@@ -0,0 +1,112 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.popups.IconAndMessagePapyrusPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.popups.MessagePapyrusPopup;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.popups.PopupNotification;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * A Builder able to create {@link PapyrusPopup} instances
+ *
+ * @author tristan faure
+ *
+ */
+public class PopupBuilder implements IBuilder {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#build(org.eclipse.papyrus.infra.widgets.toolbox.notification.PropertyWrapper,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ */
+ public INotification build(PropertyWrapper wrapper, FormToolkit toolkit) {
+ PapyrusPopup popup = null;
+ String title = "Papyrus"; //$NON-NLS-1$
+ if (wrapper.getTitle() != null) {
+ title = wrapper.getTitle();
+ }
+ String message = null;
+ if (wrapper.getMessage() != null) {
+ message = wrapper.getMessage();
+ }
+ Shell activeShell = Display.getDefault().getActiveShell();
+ if (wrapper.getType() != null) {
+ popup = new IconAndMessagePapyrusPopup(activeShell, toolkit, message, wrapper.getType());
+ } else if (wrapper.getImage() != null) {
+ popup = new IconAndMessagePapyrusPopup(activeShell, toolkit, message);
+ ((IconAndMessagePapyrusPopup) popup).setImage(wrapper.getImage());
+ } else {
+ popup = new MessagePapyrusPopup(activeShell, toolkit, message);
+ }
+ popup.setTitle(title);
+ popup.setUseHtml(wrapper.isHtml());
+ if (wrapper.getComposite() != null) {
+ popup.setCompositeCreator(wrapper.getComposite());
+ popup.setTitle(title);
+ }
+ if (wrapper.getActions() != null) {
+ popup.addRunnables(wrapper.getActions());
+ }
+ PopupNotification result = new PopupNotification(popup);
+ // assign the open result to the result of the run
+ popup.setINotification(result);
+ result.setResult(popup.open());
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#accept(java.lang.String, java.lang.Object)
+ */
+ public boolean accept(String parameterName, Object value) {
+ if (NotificationBuilder.ASYNCHRONOUS.equals(parameterName)) {
+ return value instanceof Boolean && !((Boolean) value);
+ }
+ if (NotificationBuilder.DELAY.equals(parameterName)) {
+ return false;
+ }
+ if (NotificationBuilder.TITLE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.TYPE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.IMAGE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.MESSAGE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.COMPOSITE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.HTML.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.ACTION.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.TEMPORARY.equals(parameterName)) {
+ return value instanceof Boolean && !((Boolean) value);
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PropertyWrapper.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PropertyWrapper.java
new file mode 100644
index 00000000000..48db799f622
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/PropertyWrapper.java
@@ -0,0 +1,189 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * This class provides a more comfortable usage
+ * to access to properties from NotificationBuilder map
+ *
+ * @author tristan faure
+ *
+ */
+public class PropertyWrapper {
+
+ private boolean asynchronous = false;
+
+ private String message = null;
+
+ private ICompositeCreator composite = null;
+
+ private Collection<NotificationRunnable> actions = null;
+
+ private Long delay = null;
+
+ private boolean temporary = false;
+
+ private String title = null;
+
+ private boolean html = false;
+
+ private Type type = null;
+
+ private Image image = null;
+
+ private Map<String, Object> others = new HashMap<String, Object>();
+
+ /**
+ * The class analyses the map and set the fields of the objects according to the values of the map.
+ *
+ * @param properties
+ * the map from Notification Builder
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyWrapper(Map<String, Object> properties) {
+ for (String s : properties.keySet()) {
+ if (NotificationBuilder.ASYNCHRONOUS.equals(s)) {
+ asynchronous = (Boolean) properties.get(s);
+ } else if (NotificationBuilder.COMPOSITE.equals(s)) {
+ composite = (ICompositeCreator) properties.get(s);
+ } else if (NotificationBuilder.MESSAGE.equals(s)) {
+ message = (String) properties.get(s);
+ } else if (NotificationBuilder.ACTION.equals(s)) {
+ actions = (Collection<NotificationRunnable>) properties.get(s);
+ } else if (NotificationBuilder.DELAY.equals(s)) {
+ delay = (Long) properties.get(s);
+ } else if (NotificationBuilder.HTML.equals(s)) {
+ html = (Boolean) properties.get(s);
+ } else if (NotificationBuilder.TEMPORARY.equals(s)) {
+ temporary = (Boolean) properties.get(s);
+ } else if (NotificationBuilder.TITLE.equals(s)) {
+ title = (String) properties.get(s);
+ } else if (NotificationBuilder.TYPE.equals(s)) {
+ type = (Type) properties.get(s);
+ } else if (NotificationBuilder.IMAGE.equals(s)) {
+ image = (Image) properties.get(s);
+ } else {
+ others.put(s, properties.get(s));
+ }
+ }
+ }
+
+ /**
+ * Checks if is asynchronous.
+ *
+ * @return true, if is asynchronous
+ */
+ public boolean isAsynchronous() {
+ return asynchronous;
+ }
+
+ /**
+ * Gets the message.
+ *
+ * @return the message
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Gets the composite.
+ *
+ * @return the composite
+ */
+ public ICompositeCreator getComposite() {
+ return composite;
+ }
+
+ /**
+ * Gets the actions.
+ *
+ * @return the actions
+ */
+ public Collection<NotificationRunnable> getActions() {
+ return actions;
+ }
+
+ /**
+ * Gets the delay.
+ *
+ * @return the delay
+ */
+ public Long getDelay() {
+ return delay;
+ }
+
+ /**
+ * Checks if is temporary.
+ *
+ * @return true, if is temporary
+ */
+ public boolean isTemporary() {
+ return temporary;
+ }
+
+ /**
+ * Gets the title.
+ *
+ * @return the title
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Checks if is html.
+ *
+ * @return true, if is html
+ */
+ public boolean isHtml() {
+ return html;
+ }
+
+ /**
+ * Gets the type.
+ *
+ * @return the type
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * Gets the image.
+ *
+ * @return the image
+ */
+ public Image getImage() {
+ return image;
+ }
+
+ /**
+ * Get the map containing parameters not predefined
+ *
+ * @return the map
+ */
+ public Map<String, Object> getCustomParameters() {
+ return others;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/ViewBuilder.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/ViewBuilder.java
new file mode 100644
index 00000000000..5ac8faacf14
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/builders/ViewBuilder.java
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.builders;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.AbstractInsideComposite;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.PapyrusNotificationView;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.view.ViewNotification;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * A Builder able to create {@link PapyrusNotificationView} instances
+ *
+ * @author tristan faure
+ *
+ */
+public class ViewBuilder implements IBuilder {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#build(org.eclipse.papyrus.infra.widgets.toolbox.notification.PropertyWrapper,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ */
+ public INotification build(PropertyWrapper wrapper, FormToolkit toolkit) {
+ try {
+ IViewPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(PapyrusNotificationView.ID);
+ if (part instanceof PapyrusNotificationView) {
+ PapyrusNotificationView view = (PapyrusNotificationView) part;
+ AbstractInsideComposite viewCompo = null;
+ if (wrapper.getComposite() != null) {
+ viewCompo = view.setComposite(wrapper.getComposite(), wrapper.getTitle(), wrapper.getActions(), wrapper.getType());
+ } else {
+ if (wrapper.getType() != null || wrapper.getImage() != null || wrapper.isHtml()) {
+ final Image image = wrapper.getImage();
+ final Type type = wrapper.getType();
+ final boolean isHtml = wrapper.isHtml();
+ final String message = wrapper.getMessage();
+ viewCompo = view.setComposite(new ICompositeCreator() {
+
+ public Composite createComposite(Composite parent, FormToolkit toolkit) {
+ Composite created = PapyrusControlsFactory.createCompositeWithType(Display.getDefault().getActiveShell(), toolkit, parent, type, image, message, isHtml);
+ return created;
+ }
+ }, wrapper.getTitle(), wrapper.getActions());
+ } else {
+ if (wrapper.getMessage() != null) {
+ viewCompo = view.setMessage(wrapper.getMessage(), wrapper.getTitle(), wrapper.getActions());
+ }
+ }
+ }
+ ViewNotification notification = new ViewNotification(viewCompo);
+ viewCompo.setINotification(notification);
+ return notification;
+ }
+ } catch (PartInitException e) {
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.IBuilder#accept(java.lang.String, java.lang.Object)
+ */
+ public boolean accept(String parameterName, Object value) {
+ boolean found = false;
+ for (IViewReference ref : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences()) {
+ if (PapyrusNotificationView.ID.equals(ref.getId())) {
+ found = true;
+ }
+ }
+ if (found) {
+ if (NotificationBuilder.ASYNCHRONOUS.equals(parameterName)) {
+ return value instanceof Boolean && (Boolean) value;
+ }
+ if (NotificationBuilder.TEMPORARY.equals(parameterName)) {
+ return value instanceof Boolean && !(Boolean) value;
+ }
+ if (NotificationBuilder.DELAY.equals(parameterName)) {
+ return false;
+ }
+ if (NotificationBuilder.MESSAGE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.COMPOSITE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.ACTION.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.TYPE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.TITLE.equals(parameterName)) {
+ return true;
+ }
+ if (NotificationBuilder.HTML.equals(parameterName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AbstractNotificationPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AbstractNotificationPopup.java
new file mode 100644
index 00000000000..f77b94a991e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AbstractNotificationPopup.java
@@ -0,0 +1,583 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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:
+ * Benjamin Pasero - intial API and implementation
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.ui.util.PapyrusImageUtils;
+import org.eclipse.papyrus.infra.widgets.toolbox.SwtUtil;
+import org.eclipse.papyrus.infra.widgets.toolbox.SwtUtil.FadeJob;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Monitor;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * @author Benjamin Pasero
+ * @author Mik Kersten
+ * @author Steffen Pingel
+ */
+public abstract class AbstractNotificationPopup extends Window {
+
+ private static final int TITLE_HEIGHT = 24;
+
+ private static final String LABEL_NOTIFICATION = "Notification";
+
+ private static final String LABEL_JOB_CLOSE = "CLOSE";
+
+ private static final int MAX_WIDTH = Display.getDefault().getPrimaryMonitor().getBounds().width;
+
+ private static final int MIN_HEIGHT = 100;
+
+ private static final long DEFAULT_DELAY_CLOSE = 5 * 1000;
+
+ private static final int PADDING_EDGE = 5;
+
+ private long delayClose = DEFAULT_DELAY_CLOSE;
+
+ protected LocalResourceManager resources;
+
+ private NotificationPopupColors color;
+
+ private final Display display;
+
+ private Shell shell;
+
+ private Region lastUsedRegion;
+
+ private Image lastUsedBgImage;
+
+ private final Job closeJob = new Job(LABEL_JOB_CLOSE) {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ if (!display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ Shell shell = AbstractNotificationPopup.this.getShell();
+ if (shell == null || shell.isDisposed()) {
+ return;
+ }
+
+ if (isMouseOver(shell)) {
+ scheduleAutoClose();
+ return;
+ }
+
+ AbstractNotificationPopup.this.closeFade();
+ }
+
+ });
+ }
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+
+ return Status.OK_STATUS;
+ }
+ };
+
+ private final boolean respectDisplayBounds = true;
+
+ private final boolean respectMonitorBounds = true;
+
+ private FadeJob fadeJob;
+
+ private boolean fadingEnabled;
+
+ protected final FormToolkit toolkit;
+
+ public AbstractNotificationPopup(Display display, FormToolkit toolkit) {
+ this(display, SWT.NO_TRIM | SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL, toolkit);
+ }
+
+ public AbstractNotificationPopup(Display display, int style, FormToolkit toolkit) {
+ super(new Shell(display));
+ this.toolkit = toolkit;
+ setShellStyle(style);
+
+ this.display = display;
+ resources = new LocalResourceManager(JFaceResources.getResources());
+ initResources();
+
+ closeJob.setSystem(true);
+ }
+
+ public boolean isFadingEnabled() {
+ return fadingEnabled;
+ }
+
+ public void setFadingEnabled(boolean fadingEnabled) {
+ this.fadingEnabled = fadingEnabled;
+ }
+
+ /**
+ * Override to return a customized name. Default is to return the name of
+ * the product, specified by the -name (e.g. "Eclipse SDK") command line
+ * parameter that's associated with the product ID (e.g.
+ * "org.eclipse.sdk.ide"). Strips the trailing "SDK" for any name, since
+ * this part of the label is considered visual noise.
+ *
+ * @return the name to be used in the title of the popup.
+ */
+ protected String getPopupShellTitle() {
+ String productName = "Papyrus ";
+ return productName + LABEL_NOTIFICATION;
+ }
+
+ protected Image getPopupShellImage(int maximumHeight) {
+ return PapyrusImageUtils.getDefaultIcon();
+ }
+
+ /**
+ * Override to populate with notifications.
+ *
+ * @param parent
+ */
+ protected void createContentArea(Composite parent) {
+ // empty by default
+ }
+
+ /**
+ * Override to customize the title bar
+ */
+ protected void createTitleArea(Composite parent) {
+ ((GridData) parent.getLayoutData()).heightHint = TITLE_HEIGHT;
+
+ Label titleImageLabel = new Label(parent, SWT.NONE);
+ titleImageLabel.setImage(getPopupShellImage(TITLE_HEIGHT));
+
+ Label titleTextLabel = new Label(parent, SWT.NONE);
+ titleTextLabel.setText(getPopupShellTitle());
+ titleTextLabel.setFont(CommonFonts.BOLD);
+ titleTextLabel.setForeground(getTitleForeground());
+ // titleTextLabel.setForeground(color.getTitleText());
+ titleTextLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ titleTextLabel.setCursor(parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+
+ final Label button = new Label(parent, SWT.NONE);
+ // TODO
+ // button.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE));
+ button.addMouseTrackListener(new MouseTrackAdapter() {
+
+ @Override
+ public void mouseEnter(MouseEvent e) {
+ // TODO
+ // button.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE_HOVER));
+ }
+
+ @Override
+ public void mouseExit(MouseEvent e) {
+ // TODO
+ // button.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE));
+ }
+ });
+ button.addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ close();
+ setReturnCode(CANCEL);
+ }
+
+ });
+ }
+
+ protected Color getTitleForeground() {
+ return color.getTitleText();
+ }
+
+ private void initResources() {
+ color = new NotificationPopupColors(display, resources);
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+
+ shell = newShell;
+ newShell.setBackground(color.getBorder());
+ }
+
+ @Override
+ public void create() {
+ super.create();
+ addRegion(shell);
+ }
+
+ private void addRegion(Shell shell) {
+ Region region = new Region();
+ Point s = shell.getSize();
+
+ /* Add entire Shell */
+ region.add(0, 0, s.x, s.y);
+
+ /* Subtract Top-Left Corner */
+ region.subtract(0, 0, 5, 1);
+ region.subtract(0, 1, 3, 1);
+ region.subtract(0, 2, 2, 1);
+ region.subtract(0, 3, 1, 1);
+ region.subtract(0, 4, 1, 1);
+
+ /* Subtract Top-Right Corner */
+ region.subtract(s.x - 5, 0, 5, 1);
+ region.subtract(s.x - 3, 1, 3, 1);
+ region.subtract(s.x - 2, 2, 2, 1);
+ region.subtract(s.x - 1, 3, 1, 1);
+ region.subtract(s.x - 1, 4, 1, 1);
+
+ /* Subtract Bottom-Left Corner */
+ region.subtract(0, s.y, 5, 1);
+ region.subtract(0, s.y - 1, 3, 1);
+ region.subtract(0, s.y - 2, 2, 1);
+ region.subtract(0, s.y - 3, 1, 1);
+ region.subtract(0, s.y - 4, 1, 1);
+
+ /* Subtract Bottom-Right Corner */
+ region.subtract(s.x - 5, s.y - 0, 5, 1);
+ region.subtract(s.x - 3, s.y - 1, 3, 1);
+ region.subtract(s.x - 2, s.y - 2, 2, 1);
+ region.subtract(s.x - 1, s.y - 3, 1, 1);
+ region.subtract(s.x - 1, s.y - 4, 1, 1);
+
+ /* Dispose old first */
+ if (shell.getRegion() != null) {
+ shell.getRegion().dispose();
+ }
+
+ /* Apply Region */
+ shell.setRegion(region);
+
+ /* Remember to dispose later */
+ lastUsedRegion = region;
+ }
+
+ private boolean isMouseOver(Shell shell) {
+ if (display.isDisposed()) {
+ return false;
+ }
+ return shell.getBounds().contains(display.getCursorLocation());
+ }
+
+ @Override
+ public int open() {
+ if (shell == null || shell.isDisposed()) {
+ shell = null;
+ create();
+ }
+
+ constrainShellSize();
+ shell.setLocation(fixupDisplayBounds(shell.getSize(), shell.getLocation()));
+
+ if (isFadingEnabled()) {
+ shell.setAlpha(0);
+ }
+ shell.setVisible(true);
+ fadeJob = SwtUtil.fadeIn(shell, new SwtUtil.IFadeListener() {
+
+ public void faded(Shell shell, int alpha) {
+ if (shell.isDisposed()) {
+ return;
+ }
+
+ if (alpha == 255) {
+ scheduleAutoClose();
+ }
+ }
+ });
+ return Window.OK;
+ }
+
+ protected void scheduleAutoClose() {
+ if (delayClose > 0) {
+ closeJob.schedule(delayClose);
+ }
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((GridLayout) parent.getLayout()).marginWidth = 1;
+ ((GridLayout) parent.getLayout()).marginHeight = 1;
+
+ /* Outer Composite holding the controls */
+ final Composite outerCircle = new Composite(parent, SWT.NO_FOCUS);
+ outerCircle.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ outerCircle.setBackgroundMode(SWT.INHERIT_FORCE);
+
+ outerCircle.addControlListener(new ControlAdapter() {
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ Rectangle clArea = outerCircle.getClientArea();
+ lastUsedBgImage = new Image(outerCircle.getDisplay(), clArea.width, clArea.height);
+ GC gc = new GC(lastUsedBgImage);
+
+ /* Gradient */
+ drawGradient(gc, clArea);
+
+ /* Fix Region Shape */
+ fixRegion(gc, clArea);
+
+ gc.dispose();
+
+ Image oldBGImage = outerCircle.getBackgroundImage();
+ outerCircle.setBackgroundImage(lastUsedBgImage);
+
+ if (oldBGImage != null) {
+ oldBGImage.dispose();
+ }
+ }
+
+ private void drawGradient(GC gc, Rectangle clArea) {
+ gc.setForeground(color.getGradientBegin());
+ gc.setBackground(color.getGradientEnd());
+ gc.fillGradientRectangle(clArea.x, clArea.y, clArea.width, clArea.height, true);
+ }
+
+ private void fixRegion(GC gc, Rectangle clArea) {
+ gc.setForeground(color.getBorder());
+
+ /* Fill Top Left */
+ gc.drawPoint(2, 0);
+ gc.drawPoint(3, 0);
+ gc.drawPoint(1, 1);
+ gc.drawPoint(0, 2);
+ gc.drawPoint(0, 3);
+
+ /* Fill Top Right */
+ gc.drawPoint(clArea.width - 4, 0);
+ gc.drawPoint(clArea.width - 3, 0);
+ gc.drawPoint(clArea.width - 2, 1);
+ gc.drawPoint(clArea.width - 1, 2);
+ gc.drawPoint(clArea.width - 1, 3);
+
+ /* Fill Bottom Left */
+ gc.drawPoint(2, clArea.height - 0);
+ gc.drawPoint(3, clArea.height - 0);
+ gc.drawPoint(1, clArea.height - 1);
+ gc.drawPoint(0, clArea.height - 2);
+ gc.drawPoint(0, clArea.height - 3);
+
+ /* Fill Bottom Right */
+ gc.drawPoint(clArea.width - 4, clArea.height - 0);
+ gc.drawPoint(clArea.width - 3, clArea.height - 0);
+ gc.drawPoint(clArea.width - 2, clArea.height - 1);
+ gc.drawPoint(clArea.width - 1, clArea.height - 2);
+ gc.drawPoint(clArea.width - 1, clArea.height - 3);
+ }
+ });
+
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+
+ outerCircle.setLayout(layout);
+
+ /* Title area containing label and close button */
+ final Composite titleCircle = new Composite(outerCircle, SWT.NO_FOCUS);
+ titleCircle.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ titleCircle.setBackgroundMode(SWT.INHERIT_FORCE);
+
+ layout = new GridLayout(4, false);
+ layout.marginWidth = 3;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 5;
+ layout.horizontalSpacing = 3;
+
+ titleCircle.setLayout(layout);
+
+ /* Create Title Area */
+ createTitleArea(titleCircle);
+
+ /* Outer composite to hold content controlls */
+ Composite outerContentCircle = new Composite(outerCircle, SWT.NONE);
+ outerContentCircle.setBackgroundMode(SWT.INHERIT_FORCE);
+
+ layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+
+ outerContentCircle.setLayout(layout);
+ outerContentCircle.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ outerContentCircle.setBackground(outerCircle.getBackground());
+
+ /* Middle composite to show a 1px black line around the content controls */
+ Composite middleContentCircle = new Composite(outerContentCircle, SWT.NO_FOCUS);
+ middleContentCircle.setBackgroundMode(SWT.INHERIT_FORCE);
+
+ layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.marginTop = 1;
+
+ middleContentCircle.setLayout(layout);
+ middleContentCircle.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ middleContentCircle.setBackground(color.getBorder());
+
+ /* Inner composite containing the content controls */
+ Composite innerContent = new Composite(middleContentCircle, SWT.NO_FOCUS);
+ innerContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ innerContent.setBackgroundMode(SWT.INHERIT_FORCE);
+
+ layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 5;
+ layout.marginLeft = 5;
+ layout.marginRight = 5;
+ innerContent.setLayout(layout);
+
+ innerContent.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+
+ /* Content Area */
+ createContentArea(innerContent);
+
+ setNullBackground(outerCircle);
+
+ return outerCircle;
+ }
+
+ private void setNullBackground(final Composite outerCircle) {
+ for (Control c : outerCircle.getChildren()) {
+ c.setBackground(null);
+ if (c instanceof Composite) {
+ setNullBackground((Composite) c);
+ }
+ }
+ }
+
+ @Override
+ protected void initializeBounds() {
+ Rectangle clArea = getPrimaryClientArea();
+ Point initialSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ int height = Math.max(initialSize.y, MIN_HEIGHT);
+ int width = Math.min(initialSize.x, MAX_WIDTH);
+
+ Point size = new Point(width, height);
+ shell.setLocation(clArea.width + clArea.x - size.x - PADDING_EDGE, clArea.height + clArea.y - size.y - PADDING_EDGE);
+ shell.setSize(size);
+ }
+
+ private Rectangle getPrimaryClientArea() {
+ Monitor primaryMonitor = shell.getDisplay().getPrimaryMonitor();
+ return (primaryMonitor != null) ? primaryMonitor.getClientArea() : shell.getDisplay().getClientArea();
+ }
+
+ public void closeFade() {
+ if (fadeJob != null) {
+ fadeJob.cancelAndWait(false);
+ }
+ fadeJob = SwtUtil.fadeOut(getShell(), new SwtUtil.IFadeListener() {
+
+ public void faded(Shell shell, int alpha) {
+ if (!shell.isDisposed()) {
+ if (alpha == 0) {
+ shell.close();
+ } else if (isMouseOver(shell)) {
+ if (fadeJob != null) {
+ fadeJob.cancelAndWait(false);
+ }
+ fadeJob = SwtUtil.fastFadeIn(shell, new SwtUtil.IFadeListener() {
+
+ public void faded(Shell shell, int alpha) {
+ if (shell.isDisposed()) {
+ return;
+ }
+
+ if (alpha == 255) {
+ scheduleAutoClose();
+ }
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean close() {
+ resources.dispose();
+ if (lastUsedRegion != null) {
+ lastUsedRegion.dispose();
+ }
+ if (lastUsedBgImage != null && !lastUsedBgImage.isDisposed()) {
+ lastUsedBgImage.dispose();
+ }
+ return super.close();
+ }
+
+ public long getDelayClose() {
+ return delayClose;
+ }
+
+ public void setDelayClose(long delayClose) {
+ this.delayClose = delayClose;
+ }
+
+ private Point fixupDisplayBounds(Point tipSize, Point location) {
+ if (respectDisplayBounds) {
+ Rectangle bounds;
+ Point rightBounds = new Point(tipSize.x + location.x, tipSize.y + location.y);
+
+ if (respectMonitorBounds) {
+ bounds = shell.getDisplay().getPrimaryMonitor().getBounds();
+ } else {
+ bounds = getPrimaryClientArea();
+ }
+
+ if (!(bounds.contains(location) && bounds.contains(rightBounds))) {
+ if (rightBounds.x > bounds.x + bounds.width) {
+ location.x -= rightBounds.x - (bounds.x + bounds.width);
+ }
+
+ if (rightBounds.y > bounds.y + bounds.height) {
+ location.y -= rightBounds.y - (bounds.y + bounds.height);
+ }
+
+ if (location.x < bounds.x) {
+ location.x = bounds.x;
+ }
+
+ if (location.y < bounds.y) {
+ location.y = bounds.y;
+ }
+ }
+ }
+
+ return location;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AsyncNotification.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AsyncNotification.java
new file mode 100644
index 00000000000..4771c484b14
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/AsyncNotification.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+
+/**
+ * The INotification corresponding to the async builder
+ *
+ * @author tfaure
+ *
+ */
+public class AsyncNotification implements INotification {
+
+ private final PapyrusAsyncNotificationPopup popup;
+
+ public AsyncNotification(PapyrusAsyncNotificationPopup popup) {
+ this.popup = popup;
+ }
+
+ /**
+ * delete the current notification
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification#delete()
+ */
+ public void delete() {
+ // delete immediately to avoid superposition with another
+ popup.close();
+ }
+
+ /**
+ * whether the current notification is deleted
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification#isDeleted()
+ *
+ * @return true if notification is deleted
+ */
+ public boolean isDeleted() {
+ return popup.getShell() == null || popup.getShell().isDisposed();
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/CommonFonts.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/CommonFonts.java
new file mode 100644
index 00000000000..8e01569d957
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/CommonFonts.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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:
+ * Benjamin Pasero - intial API and implementation
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Mik Kersten
+ * @since 3.0
+ */
+public class CommonFonts {
+
+ public static Font BOLD;
+
+ public static Font ITALIC;
+
+ public static Font BOLD_ITALIC;
+
+ public static Font STRIKETHROUGH = null;
+
+ public static boolean HAS_STRIKETHROUGH;
+
+ static {
+ if (Display.getCurrent() != null) {
+ init();
+ } else {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ init();
+ }
+ });
+ }
+ }
+
+ private static void init() {
+ BOLD = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
+ ITALIC = JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
+ BOLD_ITALIC = new Font(Display.getCurrent(), getModifiedFontData(ITALIC.getFontData(), SWT.BOLD | SWT.ITALIC));
+
+ Font defaultFont = JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
+ FontData[] defaultData = defaultFont.getFontData();
+ if (defaultData != null && defaultData.length == 1) {
+ FontData data = new FontData(defaultData[0].getName(), defaultData[0].getHeight(), defaultData[0].getStyle());
+
+ if ("win32".equals(SWT.getPlatform())) { //$NON-NLS-1$
+ // NOTE: Windows only, for: data.data.lfStrikeOut = 1;
+ try {
+ Field dataField = data.getClass().getDeclaredField("data"); //$NON-NLS-1$
+ Object dataObject = dataField.get(data);
+ Class<?> clazz = dataObject.getClass().getSuperclass();
+ Field strikeOutFiled = clazz.getDeclaredField("lfStrikeOut"); //$NON-NLS-1$
+ strikeOutFiled.set(dataObject, (byte) 1);
+ CommonFonts.STRIKETHROUGH = new Font(Display.getCurrent(), data);
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+ }
+ if (CommonFonts.STRIKETHROUGH == null) {
+ CommonFonts.HAS_STRIKETHROUGH = false;
+ CommonFonts.STRIKETHROUGH = defaultFont;
+ } else {
+ CommonFonts.HAS_STRIKETHROUGH = true;
+ }
+ }
+
+ /**
+ * NOTE: disposal of JFaceResources fonts handled by registry.
+ */
+ public static void dispose() {
+ if (CommonFonts.STRIKETHROUGH != null && !CommonFonts.STRIKETHROUGH.isDisposed()) {
+ CommonFonts.STRIKETHROUGH.dispose();
+ CommonFonts.BOLD_ITALIC.dispose();
+ }
+ }
+
+ /**
+ * Copied from {@link FontRegistry}
+ */
+ private static FontData[] getModifiedFontData(FontData[] baseData, int style) {
+ FontData[] styleData = new FontData[baseData.length];
+ for (int i = 0; i < styleData.length; i++) {
+ FontData base = baseData[i];
+ styleData[i] = new FontData(base.getName(), base.getHeight(), base.getStyle() | style);
+ }
+
+ return styleData;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/ImagePapyrusAsyncNotificationPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/ImagePapyrusAsyncNotificationPopup.java
new file mode 100644
index 00000000000..cfdb8d07b76
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/ImagePapyrusAsyncNotificationPopup.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * An async notification with a message and an image
+ *
+ * @author tristan faure
+ *
+ */
+public class ImagePapyrusAsyncNotificationPopup extends PapyrusAsyncNotificationPopup {
+
+ protected final Type type;
+
+ protected Image image = null;
+
+ /**
+ * Create an async popup with a specific type
+ *
+ * @param display
+ * , the display of the application
+ * @param toolkit
+ * , the toolkit able to create the controls
+ * @param type
+ * , the type of the window
+ */
+ public ImagePapyrusAsyncNotificationPopup(Display display, FormToolkit toolkit, Type type) {
+ super(display, toolkit);
+ this.type = type;
+ }
+
+ /**
+ * Set the image to display
+ *
+ * @param image
+ */
+ public void setImage(Image image) {
+ this.image = image;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusAsyncNotificationPopup#doCreateClient(org.eclipse.swt.widgets.Composite)
+ *
+ * @Override
+ */
+ @Override
+ protected void doCreateClient(Composite parent) {
+ PapyrusControlsFactory.createCompositeWithType(getShell(), null, parent, type, image, text, false);
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/NotificationPopupColors.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/NotificationPopupColors.java
new file mode 100644
index 00000000000..59c823be6c8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/NotificationPopupColors.java
@@ -0,0 +1,187 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import org.eclipse.jface.resource.DeviceResourceException;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Helper Class to create the colors for the {@link AbstractNotificationPopup}.
+ * <p>
+ * Note: Copied from FormColors of UI Forms.
+ * </p>
+ *
+ * @author Benjamin Pasero (initial contribution from RSSOwl, see bug 177974)
+ * @author Mik Kersten
+ */
+public class NotificationPopupColors {
+
+ private final Display display;
+
+ private Color titleText;
+
+ private Color gradientBegin;
+
+ private Color gradientEnd;
+
+ private Color border;
+
+ private final ResourceManager resourceManager;
+
+ public NotificationPopupColors(Display display, ResourceManager resourceManager) {
+ this.display = display;
+ this.resourceManager = resourceManager;
+
+ createColors();
+ }
+
+ private void createColors() {
+ createBorderColor();
+ createGradientColors();
+ // previously used SWT.COLOR_TITLE_INACTIVE_FOREGROUND, but too light on Windows XP
+ titleText = getColor(resourceManager, getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+ }
+
+ public Color getGradientBegin() {
+ return gradientBegin;
+ }
+
+ public Color getGradientEnd() {
+ return gradientEnd;
+ }
+
+ public Color getBorder() {
+ return border;
+ }
+
+ public Color getTitleText() {
+ return titleText;
+ }
+
+ private void createBorderColor() {
+ RGB tbBorder = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
+ RGB bg = getImpliedBackground().getRGB();
+
+ // Group 1
+ // Rule: If at least 2 of the RGB values are equal to or between 180 and
+ // 255, then apply specified opacity for Group 1
+ // Examples: Vista, XP Silver, Wn High Con #2
+ // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
+ if (testTwoPrimaryColors(tbBorder, 179, 256)) {
+ tbBorder = blend(tbBorder, bg, 70);
+ } else if (testTwoPrimaryColors(tbBorder, 120, 180)) {
+ tbBorder = blend(tbBorder, bg, 50);
+ } else {
+ tbBorder = blend(tbBorder, bg, 30);
+ }
+
+ border = getColor(resourceManager, tbBorder);
+ }
+
+ private void createGradientColors() {
+ RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
+ Color bgColor = getImpliedBackground();
+ RGB bg = bgColor.getRGB();
+ RGB bottom, top;
+
+ // Group 1
+ // Rule: If at least 2 of the RGB values are equal to or between 180 and
+ // 255, then apply specified opacity for Group 1
+ // Examples: Vista, XP Silver, Wn High Con #2
+ // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ if (testTwoPrimaryColors(titleBg, 179, 256)) {
+ bottom = blend(titleBg, bg, 30);
+ top = bg;
+ }
+
+ // Group 2
+ // Rule: If at least 2 of the RGB values are equal to or between 121 and
+ // 179, then apply specified opacity for Group 2
+ // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
+ // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ else if (testTwoPrimaryColors(titleBg, 120, 180)) {
+ bottom = blend(titleBg, bg, 20);
+ top = bg;
+ }
+
+ // Group 3
+ // Rule: If at least 2 of the RGB values are equal to or between 0 and
+ // 120, then apply specified opacity for Group 3
+ // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
+ // Aqua, Wn High Con White, Wn High Con #1
+ // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ else {
+ bottom = blend(titleBg, bg, 10);
+ top = bg;
+ }
+
+ gradientBegin = getColor(resourceManager, top);
+ gradientEnd = getColor(resourceManager, bottom);
+ }
+
+ private RGB blend(RGB c1, RGB c2, int ratio) {
+ int r = blend(c1.red, c2.red, ratio);
+ int g = blend(c1.green, c2.green, ratio);
+ int b = blend(c1.blue, c2.blue, ratio);
+ return new RGB(r, g, b);
+ }
+
+ private int blend(int v1, int v2, int ratio) {
+ int b = (ratio * v1 + (100 - ratio) * v2) / 100;
+ return Math.min(255, b);
+ }
+
+ private boolean testTwoPrimaryColors(RGB rgb, int from, int to) {
+ int total = 0;
+ if (testPrimaryColor(rgb.red, from, to)) {
+ total++;
+ }
+ if (testPrimaryColor(rgb.green, from, to)) {
+ total++;
+ }
+ if (testPrimaryColor(rgb.blue, from, to)) {
+ total++;
+ }
+ return total >= 2;
+ }
+
+ private boolean testPrimaryColor(int value, int from, int to) {
+ return value > from && value < to;
+ }
+
+ private RGB getSystemColor(int code) {
+ return getDisplay().getSystemColor(code).getRGB();
+ }
+
+ private Color getImpliedBackground() {
+ return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ }
+
+ private Display getDisplay() {
+ return display;
+ }
+
+ private Color getColor(ResourceManager manager, RGB rgb) {
+ try {
+ return manager.createColor(rgb);
+ } catch (DeviceResourceException e) {
+ return manager.getDevice().getSystemColor(SWT.COLOR_BLACK);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusAsyncNotificationPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusAsyncNotificationPopup.java
new file mode 100644
index 00000000000..5bf614e7f61
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusAsyncNotificationPopup.java
@@ -0,0 +1,139 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+
+/**
+ * This popup creates an async notification
+ *
+ * @author tristan faure
+ *
+ */
+public class PapyrusAsyncNotificationPopup extends AbstractNotificationPopup {
+
+ protected String text;
+
+ protected String title;
+
+ protected IContext context = new IContext.Context();
+
+ protected Collection<NotificationRunnable> runnables = new LinkedList<NotificationRunnable>();
+
+ public PapyrusAsyncNotificationPopup(Display display, FormToolkit toolkit) {
+ super(display, toolkit);
+ }
+
+ @Override
+ protected void createContentArea(Composite parent) {
+ super.createContentArea(parent);
+ doCreateClient(parent);
+ doCreateActionSection(parent);
+ }
+
+ protected void doCreateActionSection(Composite parent) {
+ Composite compo = toolkit.createComposite(parent);
+ compo.setLayoutData(new GridData(GridData.END, GridData.END, true, false, 1, 1));
+ compo.setLayout(new FillLayout(SWT.HORIZONTAL));
+ createRunnables(compo);
+ }
+
+ protected void createRunnables(Composite compo) {
+ if (!runnables.isEmpty()) {
+ boolean first = true;
+ for (final NotificationRunnable r : runnables) {
+ if (!first) {
+ toolkit.createLabel(compo, " ");
+ }
+ Hyperlink h = toolkit.createHyperlink(compo, r.getLabel() == null ? "run" : r.getLabel(), SWT.NONE);
+ h.addHyperlinkListener(new HyperlinkAdapter() {
+
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ PapyrusAsyncNotificationPopup.this.run(r);
+ }
+ });
+ }
+ });
+ first = false;
+ }
+ }
+ }
+
+ protected void setCompositeCreated(Composite c) {
+ context.put(IContext.COMPOSITE_CREATED, c);
+ }
+
+ /**
+ * Sets the used notification for recovering when needed (e.g. for removal)
+ *
+ * @param notification
+ * the used notification
+ */
+ public void setINotification(INotification notification) {
+ context.put(IContext.NOTIFICATION_OBJECT, notification);
+ }
+
+ protected void run(NotificationRunnable r) {
+ if (r != null) {
+ r.run(context);
+ }
+ }
+
+ protected void doCreateClient(Composite parent) {
+ Label label = new Label(parent, SWT.None);
+ label.setText(text);
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void addRunnable(NotificationRunnable runnable) {
+ runnables.add(runnable);
+ }
+
+ public void addAllRunnable(Collection<NotificationRunnable> runnable) {
+ runnables.addAll(runnable);
+ }
+
+ @Override
+ protected String getPopupShellTitle() {
+ if (title == null) {
+ return super.getPopupShellTitle();
+ }
+ return title;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusPopup.java
new file mode 100644
index 00000000000..530dec1e4e1
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/dialogs/PapyrusPopup.java
@@ -0,0 +1,222 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.papyrus.infra.ui.util.PapyrusImageUtils;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.PapyrusToolkit;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * A papyrus Popup
+ *
+ * @author tristan faure
+ *
+ */
+public abstract class PapyrusPopup extends Dialog {
+
+ protected FormToolkit toolkit;
+
+ protected boolean useHtml = false;
+
+ protected IContext context = new IContext.Context();
+
+ protected Collection<NotificationRunnable> runnables = new LinkedList<NotificationRunnable>();
+
+ protected Map<Integer, NotificationRunnable> mapForIds = new HashMap<Integer, NotificationRunnable>();
+
+ /**
+ * Used to custom the composite inside the popup
+ */
+ protected ICompositeCreator creator = null;
+
+ private String title;
+
+ public PapyrusPopup(Shell parentShell, FormToolkit toolkit) {
+ super(parentShell);
+ this.toolkit = toolkit;
+ }
+
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ getShell().setText(title == null ? "" : title);
+ getShell().setImage(PapyrusImageUtils.getDefaultIcon());
+ Composite c = (Composite) super.createDialogArea(parent);
+ c.setLayout(new FillLayout());
+ createForm(c);
+ return c;
+ }
+
+
+ /**
+ * Creates a form and a section
+ * override this method to avoid form creation
+ *
+ * @param c
+ * , the composite container
+ */
+ protected void createForm(Composite c) {
+ ScrolledForm form = toolkit.createScrolledForm(c);
+ // form.getBody().setLayoutData(new GridData(GridData.FILL_BOTH));
+ form.getBody().setLayout(new GridLayout());
+ toolkit.decorateFormHeading(form.getForm());
+ createSection(c, form);
+ c.setLayoutData(new GridData(GridData.FILL_BOTH));
+ }
+
+ /**
+ * Sets the used notification for recovering when needed (e.g. for removal)
+ *
+ * @param notification
+ * the used notification
+ */
+ public void setINotification(INotification notification) {
+ context.put(IContext.NOTIFICATION_OBJECT, notification);
+ }
+
+ /**
+ * Creates a section
+ * override this method to avoid section creation
+ *
+ * @param c
+ * , the composite container of the form
+ * @param form
+ * , the form container
+ */
+ protected void createSection(Composite c, ScrolledForm form) {
+ Section section = toolkit.createSection(form.getBody(), PapyrusToolkit.DEFAULT_STYLE);
+ section.setText("Papyrus");
+ if (creator != null && c instanceof Composite) {
+ Composite createComposite = creator.createComposite(section, toolkit);
+ section.setClient(createComposite);
+ context.put(IContext.COMPOSITE_CREATED, createComposite);
+ getShell().setFocus();
+ } else {
+ section.setClient(doCreateContents(section));
+ getShell().setFocus();
+ }
+ section.setLayoutData(new GridData(GridData.FILL_BOTH));
+ }
+
+ /**
+ * @param runnable
+ */
+ public void addRunnable(NotificationRunnable runnable) {
+ runnables.add(runnable);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ if (runnables != null && !runnables.isEmpty()) {
+ int START_AFTER_CANCEL = 2;
+ for (final NotificationRunnable r : runnables) {
+ createButton(parent, START_AFTER_CANCEL, r.getLabel(), START_AFTER_CANCEL == 2);
+ mapForIds.put(START_AFTER_CANCEL, r);
+ START_AFTER_CANCEL++;
+ }
+ } else {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ }
+ }
+
+
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ if (buttonId != IDialogConstants.OK_ID && buttonId != IDialogConstants.CANCEL_ID) {
+ NotificationRunnable run = mapForIds.get(buttonId);
+ if (run == null) {
+ super.buttonPressed(buttonId);
+ } else {
+ run.run(context);
+ // retrieve the return code according to the context if it is set
+ Object contextCode = context.get(IContext.ACTION_ID);
+ if (contextCode != null && contextCode instanceof Integer) {
+ setReturnCode((Integer) contextCode);
+ }
+ }
+ } else {
+ super.buttonPressed(buttonId);
+ }
+ close();
+ }
+
+ /**
+ * @param runnable
+ */
+ public void addRunnables(Collection<NotificationRunnable> runnable) {
+ runnables.addAll(runnable);
+ }
+
+ protected abstract Control doCreateContents(Composite composite);
+
+ public void setCompositeCreator(ICompositeCreator creator) {
+ this.creator = creator;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Gets the bounds.
+ *
+ * @return the bounds
+ */
+ public static Rectangle getBounds() {
+ Display display = Display.getDefault();
+ Rectangle bounds = display.getPrimaryMonitor().getBounds();
+ Rectangle result = new Rectangle(bounds.x + bounds.width / 4, bounds.y + bounds.height / 4, bounds.width / 2, bounds.height / 2);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#getConstrainedShellBounds(org.eclipse.swt.graphics.Rectangle)
+ */
+ @Override
+ protected Rectangle getConstrainedShellBounds(Rectangle preferredSize) {
+ // return getBounds();
+ return super.getConstrainedShellBounds(preferredSize);
+ }
+
+ public void setUseHtml(boolean useHtml) {
+ this.useHtml = useHtml;
+ }
+
+ public boolean isUseHtml() {
+ return useHtml;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/exception/NotificationException.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/exception/NotificationException.java
new file mode 100644
index 00000000000..32847630c20
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/exception/NotificationException.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.exception;
+
+
+/**
+ * An exception for the notification
+ *
+ * @author tfaure
+ *
+ */
+public class NotificationException extends RuntimeException {
+
+ /** serialization UID */
+ private static final long serialVersionUID = 3538113727604912133L;
+
+ private final String message;
+
+ public NotificationException(String message) {
+ this.message = message;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/IconAndMessagePapyrusPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/IconAndMessagePapyrusPopup.java
new file mode 100644
index 00000000000..4656cf2b07b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/IconAndMessagePapyrusPopup.java
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.popups;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.PapyrusToolkit;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+
+/**
+ * A notification with icon and message
+ *
+ * @author tristan faure
+ *
+ */
+public class IconAndMessagePapyrusPopup extends MessagePapyrusPopup {
+
+ private Type type = null;
+
+ private Image image;
+
+ public IconAndMessagePapyrusPopup(Shell parentShell, FormToolkit toolkit, String message, Type type) {
+ super(parentShell, toolkit, message);
+ this.type = type;
+ }
+
+ public IconAndMessagePapyrusPopup(Shell activeShell, FormToolkit toolkit, String message) {
+ super(activeShell, toolkit, message);
+ }
+
+
+
+ @Override
+ protected void createSection(Composite c, ScrolledForm form) {
+ Section section = toolkit.createSection(form.getBody(), PapyrusToolkit.DEFAULT_STYLE);
+ section.setText("Papyrus");
+ section.setClient(doCreateContents(section));
+ getShell().setFocus();
+ section.setLayoutData(new GridData(GridData.FILL_BOTH));
+ }
+
+ @Override
+ protected Composite createText(Composite composite) {
+ Composite top = PapyrusControlsFactory.createCompositeWithType(getShell(), toolkit, composite, type, image, message, useHtml, creator, context);
+ return top;
+ }
+
+ public void setImage(Image image) {
+ this.image = image;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/MessagePapyrusPopup.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/MessagePapyrusPopup.java
new file mode 100644
index 00000000000..eb70e24e692
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/MessagePapyrusPopup.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.popups;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusPopup;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * A notification with a message
+ *
+ * @author tristan faure
+ *
+ */
+public class MessagePapyrusPopup extends PapyrusPopup {
+
+ protected final String message;
+
+
+ /**
+ * Create a Papyrus message popup
+ *
+ * @param parentShell
+ * , the shell
+ * @param toolkit
+ * , the toolkit to create elements
+ * @param message
+ * , the message to display
+ */
+ public MessagePapyrusPopup(Shell parentShell, FormToolkit toolkit, String message) {
+ super(parentShell, toolkit);
+ this.message = message;
+
+ }
+
+ @Override
+ protected Control doCreateContents(Composite composite) {
+ composite.setLayout(getCompositeLayout());
+ Composite label = createText(composite);
+ return label;
+ }
+
+ protected Layout getCompositeLayout() {
+ return new FillLayout();
+ }
+
+ protected Composite createText(Composite composite) {
+ FormText label = toolkit.createFormText(composite, false);
+ label.setText(message, useHtml, true);
+ return label;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/PopupNotification.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/PopupNotification.java
new file mode 100644
index 00000000000..2ff2ae074c5
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/popups/PopupNotification.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.popups;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.dialogs.PapyrusPopup;
+import org.eclipse.swt.SWT;
+
+/**
+ * The INotification corresponding to the popup builder
+ *
+ * @author tfaure
+ *
+ */
+public class PopupNotification implements INotification {
+
+ private final PapyrusPopup popup;
+
+ private int popupResult = SWT.NONE;
+
+ public PopupNotification(PapyrusPopup popup) {
+ this.popup = popup;
+ }
+
+ public void delete() {
+ // no effect
+ }
+
+ /**
+ * Whether the popup has been closed
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification#isDeleted()
+ *
+ * @return true
+ */
+ public boolean isDeleted() {
+ // the object is created once the popup is closed
+ return true;
+ }
+
+ public void setResult(int popupResult) {
+ this.popupResult = popupResult;
+ }
+
+ /**
+ * Returns the result of the popup
+ *
+ * @return
+ */
+ public int getResult() {
+ return popupResult;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/utils/PapyrusControlsFactory.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/utils/PapyrusControlsFactory.java
new file mode 100644
index 00000000000..f955bf80ae8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/utils/PapyrusControlsFactory.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.utils;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.PapyrusToolkit;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+public class PapyrusControlsFactory {
+
+ /**
+ * Create a composite according to the type
+ *
+ * @param shell
+ * , the shell of the element
+ * @param toolkit
+ * , the toolkit used
+ * @param parent
+ * , the parent containing the composite created
+ * @param type
+ * , the type to create
+ * @param image
+ * , the image to associate
+ * @param message
+ * , the message to display
+ * @param useHTML
+ * , if the composite use html
+ * @return the composite created
+ */
+ public static Composite createCompositeWithType(Shell shell, FormToolkit toolkit, Composite parent, Type type, Image image, String message, boolean useHTML) {
+ return createCompositeWithType(shell, toolkit, parent, type, image, message, useHTML, null, null);
+ }
+
+ /**
+ * Create a composite according to the type
+ *
+ * @param shell
+ * , the shell of the element
+ * @param toolkit
+ * , the toolkit used
+ * @param parent
+ * , the parent containing the composite created
+ * @param type
+ * , the type to create
+ * @param image
+ * , the image to associate
+ * @param message
+ * , the message to display
+ * @param useHTML
+ * , if the composite use html
+ * @param creator
+ * , the composite creator it can be null
+ * @param context
+ * , the context to add the composite created by the creator
+ * @return the composite created
+ */
+ public static Composite createCompositeWithType(Shell shell, FormToolkit toolkit, Composite parent, Type type, Image image, String message, boolean useHTML, ICompositeCreator creator, IContext context) {
+ Composite top = null;
+ if (toolkit == null) {
+ top = new Composite(parent, SWT.None);
+ } else {
+ top = toolkit.createComposite(parent, SWT.NONE);
+ }
+ top.setLayout(new GridLayout(2, false));
+ Image anImage = image;
+ switch (type) {
+ case ERROR:
+ anImage = NotificationBuilder.getSWTImage(SWT.ICON_ERROR, shell);
+ break;
+ case INFO:
+ anImage = NotificationBuilder.getSWTImage(SWT.ICON_INFORMATION, shell);
+ break;
+ case WARNING:
+ anImage = NotificationBuilder.getSWTImage(SWT.ICON_WARNING, shell);
+ break;
+ case QUESTION:
+ anImage = NotificationBuilder.getSWTImage(SWT.ICON_QUESTION, shell);
+ break;
+ default:
+ }
+ Label labelImage = new Label(top, SWT.None);
+ if (anImage != null) {
+ labelImage.setImage(anImage);
+ }
+ if (creator == null) {
+ if (toolkit != null) {
+ FormText label = toolkit.createFormText(top, false);
+ label.setText(message, useHTML, true);
+ label.setLayoutData(new GridData(GridData.FILL_BOTH));
+ } else {
+ Label label = new Label(top, SWT.None);
+ label.setText(message);
+ label.setLayoutData(new GridData(GridData.FILL_BOTH));
+ }
+ } else {
+ if (toolkit == null) {
+ toolkit = PapyrusToolkit.INSTANCE;
+ }
+ Composite compo = creator.createComposite(top, toolkit);
+ if (context != null) {
+ context.put(IContext.COMPOSITE_CREATED, compo);
+ }
+ }
+ return top;
+ }
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/AbstractInsideComposite.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/AbstractInsideComposite.java
new file mode 100644
index 00000000000..4c3cd01ac30
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/AbstractInsideComposite.java
@@ -0,0 +1,174 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.view;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICallBack;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext;
+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.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * A composite contained in PapyrusNotificationView
+ *
+ * @author tfaure
+ */
+public abstract class AbstractInsideComposite extends Composite {
+
+ private final FormToolkit toolkit;
+
+ private Section section;
+
+ private Control previous;
+
+ private Control after;
+
+ private final ICallBack callback;
+
+ protected IContext context = new IContext.Context();
+
+ private Collection<NotificationRunnable> runnables;
+
+ AbstractInsideComposite(ICallBack callback, ScrolledForm parent, FormToolkit toolkit, Collection<NotificationRunnable> collection) {
+ super(parent.getBody(), SWT.NONE);
+ this.callback = callback;
+ this.toolkit = toolkit;
+ this.runnables = collection;
+ createContents();
+ }
+
+ /**
+ * Sets the used notification for recovering when needed (e.g. for removal)
+ *
+ * @param notification
+ * the used notification
+ */
+ public void setINotification(INotification notification) {
+ context.put(IContext.NOTIFICATION_OBJECT, notification);
+ }
+
+ private void createContents() {
+ section = toolkit.createSection(this, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
+ section.setText(getSectionName() + " - " + new SimpleDateFormat("HH'h'mm'm'ss's'").format(new Date()));
+ section.setLayout(new FillLayout());
+ Composite compo = toolkit.createComposite(section);
+ compo.setLayout(new GridLayout(1, false));
+ Control control = doCreateContents(toolkit, compo);
+ control.setLayoutData(new GridData(GridData.FILL_BOTH));
+ createHyperLinkSection(compo);
+ section.setClient(compo);
+ }
+
+ protected void createHyperLinkSection(Composite compo) {
+ Composite compoHL = toolkit.createComposite(compo);
+ compoHL.setLayout(new FillLayout());
+ if (runnables != null && !runnables.isEmpty()) {
+ for (final NotificationRunnable r : runnables) {
+ Button b = toolkit.createButton(compoHL, r.getLabel() == null ? "run" : r.getLabel(), SWT.NONE);
+ b.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ run(r);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ run(r);
+ }
+ });
+ }
+ } else {
+ Button b = toolkit.createButton(compoHL, "close", SWT.NONE);
+ b.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ close();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ close();
+ }
+ });
+ }
+ compoHL.setLayoutData(new GridData(GridData.END, GridData.END, false, true, 1, 1));
+ }
+
+ protected void setCompositeCreated(Composite c) {
+ context.put(IContext.COMPOSITE_CREATED, c);
+ }
+
+ /**
+ * Close the current Composite
+ */
+ public void close() {
+ callback.callBack(this);
+ }
+
+ public void run(NotificationRunnable r) {
+ if (r != null) {
+ r.run(context);
+ close();
+ }
+ }
+
+ public void runDefault() {
+ if (runnables != null && !runnables.isEmpty()) {
+ runnables.iterator().next().run(context);
+ }
+ close();
+ }
+
+ public void expand() {
+ section.setExpanded(true);
+ }
+
+ public void collapse() {
+ section.setExpanded(false);
+ }
+
+ protected abstract Control doCreateContents(FormToolkit toolkit, Composite composite);
+
+ protected abstract String getSectionName();
+
+ public void setAfter(Control after) {
+ this.after = after;
+ }
+
+ public Control getAfter() {
+ return after;
+ }
+
+ public void setPrevious(Control previous) {
+ this.previous = previous;
+ }
+
+ public Control getPrevious() {
+ return previous;
+ }
+
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/MessageComposite.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/MessageComposite.java
new file mode 100644
index 00000000000..a5783f3460a
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/MessageComposite.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.view;
+
+import java.util.Collection;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICallBack;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+public class MessageComposite extends AbstractInsideComposite {
+
+ protected FormText text;
+
+
+ public MessageComposite(ICallBack callBack, ScrolledForm parent, FormToolkit toolkit, Collection<NotificationRunnable> collection) {
+ super(callBack, parent, toolkit, collection);
+ setLayout(new FillLayout(SWT.HORIZONTAL));
+ }
+
+ @Override
+ protected Control doCreateContents(FormToolkit toolkit, Composite composite) {
+ text = toolkit.createFormText(composite, false);
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text.setText(text, false, false);
+ }
+
+ @Override
+ protected String getSectionName() {
+ return "Message";
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/PapyrusNotificationView.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/PapyrusNotificationView.java
new file mode 100644
index 00000000000..a6d5a7d99fb
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/PapyrusNotificationView.java
@@ -0,0 +1,417 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.view;
+
+
+import java.util.Collection;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.papyrus.infra.ui.util.PapyrusImageUtils;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICallBack;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.PapyrusToolkit;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.utils.PapyrusControlsFactory;
+import org.eclipse.papyrus.infra.widgets.toolbox.utils.ToolbooxImageUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.part.ViewPart;
+
+
+/**
+ * This view displays a list of notifications for users
+ */
+
+public class PapyrusNotificationView extends ViewPart implements ICallBack {
+
+ /**
+ * The ID of the view as specified by the extension.
+ */
+ public static final String ID = "org.eclipse.papyrus.infra.widgets.toolbox.notification.view.PapyrusNotificationView";
+
+ private Action closeAllAction;
+
+ private Action collapseAllAction;
+
+ private Action allDefaultAction;
+
+ private boolean isCollapse = true;
+
+ private ScrolledForm form;
+
+ private FormToolkit toolkit = PapyrusToolkit.INSTANCE;
+
+ /**
+ * The constructor.
+ */
+ public PapyrusNotificationView() {
+ }
+
+ /**
+ * This is a callback that will allow us
+ * to create the viewer and initialize it.
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ setTitleImage(PapyrusImageUtils.getDefaultIcon());
+ createContent(parent);
+ makeActions();
+ hookContextMenu();
+ hookDoubleClickAction();
+ contributeToActionBars();
+ }
+
+ /**
+ * Add a composite in the view
+ *
+ * @param creator
+ * , the composite creator
+ * @param collection
+ * , the collection of actions
+ * @return the composite
+ */
+ public AbstractInsideComposite setComposite(final ICompositeCreator creator, Collection<NotificationRunnable> collection) {
+ MessageComposite composite = new MessageComposite(this, form, toolkit, collection) {
+
+ @Override
+ protected Control doCreateContents(FormToolkit toolkit, Composite compo) {
+ Composite composite = creator.createComposite(compo, toolkit);
+ setCompositeCreated(composite);
+ return composite;
+ }
+
+ };
+ manageComposite(composite);
+ return composite;
+ }
+
+ /**
+ * Add a composite in the view
+ *
+ * @param creator
+ * , the composite creator
+ * @param messageTitle
+ * , the message in the section
+ * @param collection
+ * , the collection of actions
+ * @return the composite
+ */
+ public AbstractInsideComposite setComposite(final ICompositeCreator creator, final String messageTitle, Collection<NotificationRunnable> runnables) {
+ return setComposite(creator, messageTitle, runnables, null);
+ }
+
+ /**
+ * Add a composite in the view
+ *
+ * @param creator
+ * , the composite creator
+ * @param messageTitle
+ * , the message in the section
+ * @param collection
+ * , the collection of actions
+ * @return the composite
+ */
+ public AbstractInsideComposite setComposite(final ICompositeCreator creator, final String messageTitle, Collection<NotificationRunnable> runnables, final Type type) {
+ MessageComposite composite = new MessageComposite(this, form, toolkit, runnables) {
+
+ @Override
+ protected Control doCreateContents(FormToolkit toolkit, Composite composite) {
+ Composite compo = null;
+ if (type != null) {
+ compo = PapyrusControlsFactory.createCompositeWithType(Display.getDefault().getActiveShell(), toolkit, composite, type, null, null, false, creator, context);
+ } else {
+ compo = creator.createComposite(composite, toolkit);
+ setCompositeCreated(compo);
+ }
+ return compo;
+ }
+
+ @Override
+ protected String getSectionName() {
+ if (messageTitle == null) {
+ return super.getSectionName();
+ } else {
+ return messageTitle;
+ }
+ }
+ };
+ manageComposite(composite);
+ return composite;
+ }
+
+ /**
+ * Add a composite in the view
+ *
+ * @param message
+ * , the message in the composite
+ * @param title
+ * , the title of the section
+ * @param runnables
+ * , the actions
+ * @return
+ */
+ public AbstractInsideComposite setMessage(String message, final String title, Collection<NotificationRunnable> runnables) {
+ MessageComposite compo = new MessageComposite(this, form, toolkit, runnables) {
+
+ @Override
+ protected String getSectionName() {
+ if (title == null) {
+ return super.getSectionName();
+ } else {
+ return title;
+ }
+ }
+ };
+ compo.setText(message);
+ manageComposite(compo);
+ return compo;
+ }
+
+ /**
+ * Add a message in the view
+ *
+ * @param message
+ * , the message to display
+ */
+ public void setMessage(String message) {
+ setMessage(message, null);
+ }
+
+ /**
+ * Add a message with a collection of actions
+ *
+ * @param message
+ * , the message to display
+ * @param runnables
+ * , a collection of actions
+ */
+ public void setMessage(String message, Collection<NotificationRunnable> runnables) {
+ MessageComposite compo = new MessageComposite(this, form, toolkit, runnables);
+ compo.setText(message);
+ manageComposite(compo);
+ }
+
+ private void manageComposite(AbstractInsideComposite compo) {
+ if (form.getBody().getChildren().length > 1) {
+ Control previous = form.getBody().getChildren()[form.getBody().getChildren().length - 2];
+ manageComposite(compo, previous);
+ } else {
+ manageComposite(compo, null);
+ }
+
+ }
+
+ private void manageComposite(Control created, Control previous) {
+ FormData data = new FormData();
+ if (previous != null) {
+ data.bottom = new FormAttachment(previous, -5);
+ } else {
+ data.bottom = new FormAttachment(98, -5);
+ }
+ data.left = new FormAttachment(0, 5);
+
+ data.right = new FormAttachment(100, -5);
+ created.setLayoutData(data);
+ form.reflow(true);
+ if (created instanceof AbstractInsideComposite) {
+ AbstractInsideComposite inside = (AbstractInsideComposite) created;
+ inside.setPrevious(previous);
+ }
+ if (previous instanceof AbstractInsideComposite) {
+ AbstractInsideComposite inside = (AbstractInsideComposite) previous;
+ inside.setAfter(created);
+ }
+ created.setFocus();
+ }
+
+ private void createContent(Composite parent) {
+ parent.setLayout(new FillLayout(SWT.VERTICAL));
+ form = toolkit.createScrolledForm(parent);
+ form.getBody().setLayout(new FormLayout());
+ form.setShowFocusedControl(true);
+ }
+
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+
+ public void menuAboutToShow(IMenuManager manager) {
+ PapyrusNotificationView.this.fillContextMenu(manager);
+ }
+ });
+ }
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ fillLocalPullDown(bars.getMenuManager());
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalPullDown(IMenuManager manager) {
+ manager.add(allDefaultAction);
+ manager.add(closeAllAction);
+ manager.add(collapseAllAction);
+ manager.add(new Separator());
+ }
+
+ private void fillContextMenu(IMenuManager manager) {
+ }
+
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(allDefaultAction);
+ manager.add(closeAllAction);
+ manager.add(collapseAllAction);
+ }
+
+ private void makeActions() {
+ allDefaultAction = new Action() {
+
+ @Override
+ public void run() {
+ for (Control c : form.getBody().getChildren()) {
+ if (c instanceof AbstractInsideComposite) {
+ AbstractInsideComposite compo = (AbstractInsideComposite) c;
+ compo.runDefault();
+ }
+ }
+ form.getBody().layout(true, true);
+ form.layout(true, true);
+ }
+ };
+ allDefaultAction.setText("Run all default action");
+ allDefaultAction.setToolTipText("Run all default action");
+ allDefaultAction.setImageDescriptor(ToolbooxImageUtils.getImageDescriptor(org.eclipse.papyrus.infra.widgets.toolbox.utils.ISharedImages.IMG_RUN));
+ closeAllAction = new Action() {
+
+ @Override
+ public void run() {
+ for (Control c : form.getBody().getChildren()) {
+ c.dispose();
+ }
+ form.getBody().layout(true, true);
+ form.layout(true, true);
+ }
+ };
+ closeAllAction.setText("Close All");
+ closeAllAction.setToolTipText("Close all the messages");
+ closeAllAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE));
+ collapseAllAction = new Action() {
+
+ @Override
+ public void run() {
+ for (Control c : form.getBody().getChildren()) {
+ if (c instanceof AbstractInsideComposite) {
+ AbstractInsideComposite compo = (AbstractInsideComposite) c;
+ if (isCollapse) {
+ compo.collapse();
+ } else {
+ compo.expand();
+ }
+ }
+ }
+ isCollapse = !isCollapse;
+ if (isCollapse) {
+ collapseAllAction.setText("Collapse all the messages");
+ collapseAllAction.setToolTipText("Collapse all the messages");
+ } else {
+ collapseAllAction.setText("Expand all the messages");
+ collapseAllAction.setToolTipText("Expand all the messages");
+ }
+ form.getBody().layout(true, true);
+ form.layout(true, true);
+ }
+ };
+ collapseAllAction.setText("Collapse all the messages");
+ collapseAllAction.setToolTipText("Collapse all the messages");
+ collapseAllAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_COLLAPSEALL));
+ }
+
+ private void hookDoubleClickAction() {
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ @Override
+ public void setFocus() {
+ form.setFocus();
+ }
+
+ /*
+ * (non-Javadoc)
+ * this method update the after and previous attributes to update the layout
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.view.ICloseCallBack#closed(java.lang.Object)
+ */
+ public void callBack(Object element) {
+ destroy(element);
+ }
+
+ /**
+ * This method destroy the object if it is contained in the view
+ *
+ * @param element
+ */
+ protected void destroy(Object element) {
+ if (element instanceof AbstractInsideComposite) {
+ AbstractInsideComposite inside = (AbstractInsideComposite) element;
+
+ if (inside != null) {
+ Control previous = inside.getPrevious();
+ Control after = inside.getAfter();
+
+ if ((after != null) && !(after.isDisposed())
+ && ((previous == null) || !(previous.isDisposed()))) {
+
+ // previous can be null but can not be disposed when not null
+ // after can not be null nor disposed
+ manageComposite(after, previous);
+
+ } else if ((previous instanceof AbstractInsideComposite) && !(previous.isDisposed())) {
+ AbstractInsideComposite compo = (AbstractInsideComposite) previous;
+ compo.setAfter(null);
+ // FormData data = new FormData();
+ // data.bottom = new FormAttachment(previous, -5);
+ // data.left = new FormAttachment(0, 5);
+ // data.right = new FormAttachment(100, -5);
+ // compo.setLayoutData(data);
+ // form.reflow(true);
+ }
+ }
+
+ if (!inside.isDisposed()) {
+ inside.dispose();
+ }
+
+ form.getBody().layout(true, true);
+ form.layout(true, true);
+ }
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/ViewNotification.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/ViewNotification.java
new file mode 100644
index 00000000000..dac34dae29b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/notification/view/ViewNotification.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.notification.view;
+
+import org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification;
+
+/**
+ * The INotification corresponding to the view builder
+ *
+ * @author tfaure
+ *
+ */
+public class ViewNotification implements INotification {
+
+ private final AbstractInsideComposite viewCompo;
+
+ public ViewNotification(AbstractInsideComposite viewCompo) {
+ this.viewCompo = viewCompo;
+ }
+
+ public void delete() {
+ viewCompo.close();
+ }
+
+ /**
+ *
+ * whether the current notification is deleted
+ *
+ * @see org.eclipse.papyrus.infra.widgets.toolbox.notification.INotification#isDeleted()
+ * @return true if notification is deleted
+ */
+ public boolean isDeleted() {
+ return viewCompo.isDisposed();
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/DialogUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/DialogUtils.java
new file mode 100644
index 00000000000..0449f67cf07
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/DialogUtils.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * 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:
+ * Ansgar Radermacher ansgar.radermacher@cea.fr
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.widgets.toolbox.utils;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.dialogs.FilteredList;
+
+/**
+ * Some static utility functions in the context of dialogs
+ */
+public class DialogUtils {
+
+ /**
+ * Create a filtered list that automatically uses the available space (@see createFillGridData)
+ * and a width & height hint
+ *
+ * @param parent
+ * the parent composite
+ * @param labelProvider
+ * the label provider for the filtered list
+ * @param width
+ * a with hint
+ * @param height
+ * a height hint
+ * @param style
+ * the style of the filtered list
+ * @return the created list
+ */
+ public static FilteredList createFilteredList(Composite parent, ILabelProvider labelProvider,
+ int width, int height, int style) {
+ FilteredList list = new FilteredList(parent, style, labelProvider,
+ true, true, true);
+
+ GridData data = createFillGridData();
+ data.widthHint = width;
+ data.heightHint = height;
+ list.setLayoutData(data);
+ list.setFont(parent.getFont());
+ return list;
+ }
+
+ /**
+ * Create a composite containing a label and a combo box within a given parent composite
+ * The label is positioned left of the button
+ *
+ * @param parent
+ * the parent composite
+ * @param label
+ * the text of the label
+ * @param comboFlags
+ * SWT flags for the combo box
+ * @param compFlags
+ * SWT flags for the created composite (that contains combo and label)
+ * @return
+ */
+ public static Combo createComboWithText(Composite parent, String label, int comboFlags, int compFlags) {
+ Composite comboComposite = new Composite(parent, compFlags);
+ comboComposite.setLayout(new GridLayout(2, false));
+ Label comboLabel = new Label(comboComposite, SWT.NONE);
+ comboLabel.setText(label);
+ Combo combo = new Combo(comboComposite, comboFlags);
+ comboComposite.pack();
+ return combo;
+ }
+
+ /**
+ * Create a composite containing a label and a button within a given parent composite
+ * The label is positioned left of the combo box
+ *
+ * @param parent
+ * the parent composite
+ * @param label
+ * the text of the label
+ * @param buttonFlags
+ * SWT flags for the button
+ * @param compFlags
+ * SWT flags for the created composite (that contains combo and label)
+ * @return
+ */
+ public static Button createButtonWithText(Composite parent, String label, int buttonFlags, int compFlags) {
+ Composite buttonComposite = new Composite(parent, compFlags);
+ buttonComposite.setLayout(new GridLayout(2, false));
+ Label buttonLabel = new Label(buttonComposite, SWT.NONE);
+ buttonLabel.setText(label);
+ Button button = new Button(buttonComposite, buttonFlags);
+ buttonComposite.pack();
+ return button;
+ }
+
+ /**
+ * Create a GridData object which fills the available vertical and horizontal space
+ *
+ * @return
+ */
+ public static GridData createFillGridData() {
+ GridData gridData = new GridData();
+ gridData.grabExcessVerticalSpace = true;
+ gridData.grabExcessHorizontalSpace = true;
+ gridData.horizontalAlignment = GridData.FILL;
+ gridData.verticalAlignment = GridData.FILL;
+ return gridData;
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ISharedImages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ISharedImages.java
new file mode 100644
index 00000000000..c4a7dd95320
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ISharedImages.java
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.utils;
+
+
+/**
+ * Constants to use in {@link ToolbooxImageUtils}
+ *
+ * @author tfaure
+ *
+ */
+public interface ISharedImages {
+
+ int IMG_RUN = 0;
+
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ToolbooxImageUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ToolbooxImageUtils.java
new file mode 100644
index 00000000000..5eede25823c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets.toolbox/src/org/eclipse/papyrus/infra/widgets/toolbox/utils/ToolbooxImageUtils.java
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * Copyright (c) 2010 ATOS ORIGIN.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.toolbox.utils;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.papyrus.infra.widgets.toolbox.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * A class retrieving the icons used in papyrus toolbox
+ *
+ * @author tfaure
+ *
+ */
+public class ToolbooxImageUtils {
+
+ /**
+ * Returns an image according to {@link ISharedImages}
+ *
+ * @param id
+ * , the constant
+ * @return
+ */
+ public static Image getImage(int id) {
+ StringBuffer path = new StringBuffer("/icons/");
+ switch (id) {
+ case ISharedImages.IMG_RUN:
+ path = path.append("run.gif");
+ break;
+ default:
+ break;
+ }
+ String key = Activator.PLUGIN_ID + path;
+ Image result = JFaceResources.getImageRegistry().get(key);
+ if (result == null) {
+ URL url = Activator.getDefault().getBundle().getEntry(path.toString());
+ try {
+ result = new Image(Display.getDefault(), url.openStream());
+ JFaceResources.getImageRegistry().put(key, result);
+ } catch (IOException e) {
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns an image descriptor according to {@link ISharedImages}
+ *
+ * @param id
+ * , the constant
+ * @return
+ */
+ public static ImageDescriptor getImageDescriptor(final int id) {
+ return new ImageDescriptor() {
+
+ @Override
+ public ImageData getImageData() {
+ return getImage(id).getImageData();
+ }
+ };
+ }
+}
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.checkstyle b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.checkstyle
new file mode 100644
index 00000000000..75246d341f9
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.checkstyle
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <fileset name="all" enabled="true" check-config-name="Sun Checks" local="false">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+</fileset-config>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.classpath b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.project b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.project
new file mode 100644
index 00000000000..6c2049aab43
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.infra.widgets</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.core.resources.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..58763b1afa7
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/org/eclipse/papyrus/editors/messages/messages.properties=ISO-8859-1
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 00000000000..b3aa6d60f94
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,291 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=260
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=260
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.ui.prefs b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..954281dbc31
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,68 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Papyrus
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Papyrus
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..fd449867eca
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF
@@ -0,0 +1,36 @@
+Manifest-Version: 1.0
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.core.databinding,
+ org.eclipse.jface.databinding,
+ org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.100",
+ org.eclipse.core.resources;bundle-version="3.7.100",
+ org.eclipse.papyrus.infra.tools;bundle-version="1.2.0",
+ com.ibm.icu;bundle-version="4.4.2",
+ org.eclipse.papyrus.infra.services.labelprovider;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
+ org.eclipse.jface.text;bundle-version="3.10.0",
+ org.eclipse.emf.edit;bundle-version="2.12.0"
+Export-Package: org.eclipse.papyrus.infra.widgets,
+ org.eclipse.papyrus.infra.widgets.creation,
+ org.eclipse.papyrus.infra.widgets.databinding,
+ org.eclipse.papyrus.infra.widgets.editors,
+ org.eclipse.papyrus.infra.widgets.messages,
+ org.eclipse.papyrus.infra.widgets.providers,
+ org.eclipse.papyrus.infra.widgets.selectors,
+ org.eclipse.papyrus.infra.widgets.strategy,
+ org.eclipse.papyrus.infra.widgets.util,
+ org.eclipse.papyrus.infra.widgets.validator,
+ org.eclipse.papyrus.infra.widgets.widgets,
+ org.eclipse.papyrus.infra.widgets.wizard.pages
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.2.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Localization: plugin
+Bundle-ManifestVersion: 2
+Bundle-Activator: org.eclipse.papyrus.infra.widgets.Activator
+Bundle-Description: %pluginDescription
+Bundle-SymbolicName: org.eclipse.papyrus.infra.widgets;singleton:=true
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/about.html b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/about.html
new file mode 100644
index 00000000000..d35d5aed64c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/build.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/build.properties
new file mode 100644
index 00000000000..8080cf00176
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/build.properties
@@ -0,0 +1,12 @@
+#
+#Mon Sep 12 09:30:25 CEST 2011
+bin.includes = META-INF/,\
+ .,\
+ icons/,\
+ plugin.properties,\
+ about.html,\
+ plugin.xml
+output..=bin/
+src.includes = about.html
+source..=src/
+bin..=bin/
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/AddReg.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/AddReg.gif
new file mode 100644
index 00000000000..8493df40dfe
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/AddReg.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_12x12.gif
new file mode 100644
index 00000000000..189b46e5a5b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_16x16.gif
new file mode 100644
index 00000000000..252d7ebcb8c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Add_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowDown_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowDown_16x16.gif
new file mode 100644
index 00000000000..072b1844572
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowDown_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowUp_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowUp_16x16.gif
new file mode 100644
index 00000000000..07164754e5c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/ArrowUp_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_12x12.gif
new file mode 100644
index 00000000000..bd924a5e0fa
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_16x16.gif
new file mode 100644
index 00000000000..b6922ac11cf
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Delete_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Down_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Down_12x12.gif
new file mode 100644
index 00000000000..c0672e72a2b
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Down_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_12x12.gif
new file mode 100644
index 00000000000..0b0bcd15539
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_16x16.gif
new file mode 100644
index 00000000000..17d8b2e7aa0
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Edit_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/PapyrusLogo16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/PapyrusLogo16x16.gif
new file mode 100644
index 00000000000..8a31f458379
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/PapyrusLogo16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Switch_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Switch_12x12.gif
new file mode 100644
index 00000000000..9a6070c38ef
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Switch_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Up_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Up_12x12.gif
new file mode 100644
index 00000000000..9620d683cbd
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/Up_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_double.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_double.gif
new file mode 100644
index 00000000000..c02db2c9df4
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_double.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left.gif
new file mode 100644
index 00000000000..4fb41501036
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left_double.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left_double.gif
new file mode 100644
index 00000000000..336b55cf08e
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_left_double.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_right.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_right.gif
new file mode 100644
index 00000000000..19567890aa8
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/arrow_right.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-filesystem_12x12.png b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-filesystem_12x12.png
new file mode 100644
index 00000000000..bdd513d2405
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-filesystem_12x12.png
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-workspace_12x12.png b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-workspace_12x12.png
new file mode 100644
index 00000000000..a9461a35269
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse-workspace_12x12.png
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse_12x12.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse_12x12.gif
new file mode 100644
index 00000000000..b53ced50f96
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/browse_12x12.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/error.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/error.gif
new file mode 100644
index 00000000000..9b048d60532
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/error.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/hyperlink_16x16.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/hyperlink_16x16.gif
new file mode 100644
index 00000000000..1e09d979520
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/hyperlink_16x16.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/papyrus.png b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/papyrus.png
new file mode 100644
index 00000000000..0f74e27b483
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/papyrus.png
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/refresh.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/refresh.gif
new file mode 100644
index 00000000000..e3831471a65
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/refresh.gif
Binary files differ
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.properties
new file mode 100644
index 00000000000..a566c99ea30
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.properties
@@ -0,0 +1,13 @@
+#################################################################################
+# 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
+##################################################################################
+providerName = Eclipse Modeling Project
+pluginName = Papyrus widgets
+pluginDescription=This plug-in contains a set of SWT widgets for editing different kind of elements. These widgets should be used as a standard in Papyrus. Most of them can be used in two different ways: - Eclipse Databinding - setValue/getValue \ No newline at end of file
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.xml
new file mode 100644
index 00000000000..257978e8e4c
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.papyrus.infra.services.labelprovider.labelProvider">
+ <labelProvider
+ priority="10"
+ provider="org.eclipse.papyrus.infra.widgets.providers.WorkbenchFilteredLabelProvider">
+ </labelProvider>
+ </extension>
+
+</plugin>
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/pom.xml
new file mode 100644
index 00000000000..3ee11efad95
--- /dev/null
+++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.papyrus.infra.widgets</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project>
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;
+ }
+}
diff --git a/plugins/infra/ui/pom.xml b/plugins/infra/ui/pom.xml
new file mode 100644
index 00000000000..589c9e1afcd
--- /dev/null
+++ b/plugins/infra/ui/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>org.eclipse.papyrus.infra-ui</artifactId>
+ <packaging>pom</packaging>
+ <parent>
+ <groupId>org.eclipse.papyrus</groupId>
+ <artifactId>org.eclipse.papyrus.infra</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <name>Papyrus Infra UI</name>
+ <description>The principal common User Interface components of Papyrus, including the core Editor APIs.</description>
+
+ <modules>
+ <module>org.eclipse.papyrus.infra.ui</module>
+ <module>org.eclipse.papyrus.infra.ui.resources</module>
+ <module>org.eclipse.papyrus.infra.onefile.ui</module>
+ <module>org.eclipse.papyrus.infra.widgets</module>
+ <module>org.eclipse.papyrus.infra.widgets.toolbox</module>
+ </modules>
+</project>

Back to the top