Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups')
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.classpath7
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.project28
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/META-INF/MANIFEST.MF25
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/about.html28
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/build.properties7
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/messages.properties23
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.properties11
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.xml18
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/schema/org.eclipse.papyrus.diagram.common.groups.groupcontainment.exsd205
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Activator.java65
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Messages.java100
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeGraphicalParentCommand.java476
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeModelParentCommand.java132
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseChildrenNotificationCommand.java214
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseParentNotificationCommand.java219
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/CommandResultMessagesError.java10
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/SetUpReferencesCommand.java100
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/UpdateReferencesCommand.java157
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/utlis/CommandsUtils.java1172
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/GroupNotificationBuilderFactory.java90
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/PendingGroupNotificationsManager.java181
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/groupcontainment/GroupContainmentRegistry.java268
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CheckboxIGraphicalFocusListenner.java52
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseChildrenNotificationConfigurator.java293
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseParentNotificationConfigurator.java264
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CompositeCreatorWithCommand.java122
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/NotificationConfigurator.java157
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/utils/CreatorUtils.java121
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/DefaultModelParent.java59
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/Utils.java1048
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/CreateInGroupEditPolicy.java214
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/XYLayoutEditGroupPolicy.java456
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/groupcontainment/AbstractContainerNodeDescriptor.java158
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityFactoryHelper.java84
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityGroup.java66
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSection.java47
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSectionFilter.java50
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GraphicalAndModelElementComparator.java176
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GroupRequestConstants.java55
40 files changed, 6966 insertions, 0 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.classpath b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.classpath
new file mode 100644
index 00000000000..2d1a4302f04
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.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/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.project b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.project
new file mode 100644
index 00000000000..ec8311ec2fa
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.diagram.common.groups</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/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.settings/org.eclipse.jdt.core.prefs b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..ef48b899f0b
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu May 20 10:49:25 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/META-INF/MANIFEST.MF b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..0aa275727d6
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.gmf.runtime.diagram.ui.properties,
+ org.eclipse.papyrus.diagram.common;bundle-version:="0.9.0",
+ org.eclipse.papyrus.ui.toolbox;bundle-version:="0.9.0",
+ org.eclipse.papyrus.preferences;bundle-version="0.9.0"
+Export-Package: org.eclipse.papyrus.diagram.common.groups.commands,
+ org.eclipse.papyrus.diagram.common.groups.core.utils,
+ org.eclipse.papyrus.diagram.common.groups.edit.policies,
+ org.eclipse.papyrus.diagram.common.groups.groupcontainment,
+ org.eclipse.papyrus.diagram.common.groups.preferences,
+ org.eclipse.papyrus.diagram.common.groups.tabbedproperties.appearance,
+ org.eclipse.papyrus.diagram.common.groups.utils
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 0.9.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Localization: plugin
+Bundle-ManifestVersion: 2
+Bundle-Activator: org.eclipse.papyrus.diagram.common.groups.Activator
+Bundle-SymbolicName: org.eclipse.papyrus.diagram.common.groups;singlet
+ on:=true
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/about.html b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/about.html
new file mode 100644
index 00000000000..82d49bf5f81
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/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/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/build.properties b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/build.properties
new file mode 100644
index 00000000000..7c52a3acb16
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/build.properties
@@ -0,0 +1,7 @@
+#
+#Mon Sep 12 09:29:44 CEST 2011
+bin.includes=META-INF/,.,plugin.xml,messages.properties,plugin.properties,schema/,about.html
+output..=bin/
+src.includes=schema/,META-INF/,.,plugin.xml,messages.properties,plugin.properties,about.html
+source..=src/
+bin..=bin/
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/messages.properties b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/messages.properties
new file mode 100644
index 00000000000..faaf1815b1c
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/messages.properties
@@ -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
+#
+####################################################################################
+# Notification messages
+ChooseContainedElementsCreator_Message=Choose which children should be contained in the group {0}.
+ChooseContainedElementsCreator_CheckAll=Check / Uncheck all
+ChooseContainedElementsCreator_Run=Assign
+ChooseContainingGroupCreator_Message=Choose which parent these elements must be attached to.
+ChooseContainingGroupCreator_Contained={0} must be contained by :
+ChooseContainingGroupCreator_Run=Assign
+ChooseParentNotificationCommand_ChooseGraphicalParent=Several Graphical parents are available, choose one of them :
+ChooseParentNotificationCommand_ChooseModelParent=The zone in which you have created your element have several model parents available, this kind of zone should be avoided. Please choose one of them :
+ChooseChildrenICompositeCreator_ChooseChildren=Choose graphical children:
+ChooseParentNotificationCommand_ChooseGraphicalParentMessage=Select the graphical parent of
+ChooseParentNotificationCommand_ChooseGraphicalChildrenMessage=Select the graphical children of
+CommandsUtils_HandleGraphicalChildrenMovingOut_Label=Updating element which are not graphical children anymore \ No newline at end of file
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.properties b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.properties
new file mode 100644
index 00000000000..93449472c26
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.properties
@@ -0,0 +1,11 @@
+##########################################################################################
+# 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)
+#
+########################################################################################
+pluginName=Papyrus Common groups plugin (Incubation)
+providerName=Eclipse Modeling Project
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.xml b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.xml
new file mode 100644
index 00000000000..7e32c46ce8d
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension-point id="org.eclipse.papyrus.diagram.common.groups.groupcontainment" name="group containment" schema="schema/org.eclipse.papyrus.diagram.common.groups.groupcontainment.exsd"/>
+ <extension
+ point="org.eclipse.ui.views.properties.tabbed.propertySections">
+ <propertySections
+ contributorId="TreeOutlinePage">
+ <propertySection
+ class="org.eclipse.papyrus.diagram.common.groups.tabbedproperties.appearance.ChooseGraphicalParentSection"
+ filter="org.eclipse.papyrus.diagram.common.groups.tabbedproperties.appearance.ChooseGraphicalParentSectionFilter"
+ id="org.eclipse.papyrus.tabbedproperties.appearance.chooseGraphicalParentSection"
+ tab="org.eclipse.papyrus.tabbedproperties.appearance.appearancetab">
+ </propertySection>
+ </propertySections>
+ </extension>
+
+</plugin>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/schema/org.eclipse.papyrus.diagram.common.groups.groupcontainment.exsd b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/schema/org.eclipse.papyrus.diagram.common.groups.groupcontainment.exsd
new file mode 100644
index 00000000000..6f6ec7fc5ad
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/schema/org.eclipse.papyrus.diagram.common.groups.groupcontainment.exsd
@@ -0,0 +1,205 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.diagram.common.groups" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.diagram.common.groups" id="org.eclipse.papyrus.diagram.common.groups.groupcontainment" name="group containment"/>
+ </appinfo>
+ <documentation>
+ This extension point allows to register group types and their relationship with contained objects, in order to let the group framework handle the graphical parent reassignation.
+
+Diagrams using this extension point must register their diagram part to the group framework.
+This can be achieved calling the code :
+ //configure group framework
+ EditingDomainRegisteringService.addGroupFrameworkForEditingDomain(getEditingDomain(), getDiagramEditPart());
+at the end of the initializeGraphicalViewer() method,
+in the class org.eclipse.papyrus.diagram.***.Uml***DiagramForMultiEditor extending org.eclipse.papyrus.diagram.***.part.UMLDiagramEditor, which itself extends org.eclipse.papyrus.diagram.common.part.UmlGmfDiagramEditor.
+
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ <documentation>
+ The group containment extension allows to declare a set of group types, which can share the same contained elements.
+
+Node representing instances of these types can all be the graphical parent of a same element.
+
+Declaring them in this extension will let the groups framework handle conflicts for deciding which is the graphical parent.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <choice>
+ <element ref="modelContainer"/>
+ <element ref="referenceContainer"/>
+ </choice>
+ </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="modelContainer">
+ <annotation>
+ <documentation>
+ A model container declaration must be used when a group is the model direct parent of its contained elements.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="editPartType" type="string">
+ <annotation>
+ <documentation>
+ The type of edit part for which we should use this descriptor.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="descriptor" type="string">
+ <annotation>
+ <documentation>
+ The class describing the group type and how it is related to its contained children.
+This class must implement org.eclipse.papyrus.diagram.common.groups.groupcontainment.IContainerNodeDescriptor
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.diagram.common.groups.groupcontainment.IContainerNodeDescriptor"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="referenceContainer">
+ <annotation>
+ <documentation>
+ A reference container declaration must be used when a group is not the model direct parent of its contained elements, but contains elements through a reference with a specific feature.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="editPartType" type="string">
+ <annotation>
+ <documentation>
+ The type of edit part for which we should use this descriptor.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="descriptor" type="string">
+ <annotation>
+ <documentation>
+ The class describing the group type and how it is related to its contained children.
+This class must implement org.eclipse.papyrus.diagram.common.groups.groupcontainment.IContainerNodeDescriptor
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.diagram.common.groups.groupcontainment.IContainerNodeDescriptor"/>
+ </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>
+ &lt;extension
+ point=&quot;org.eclipse.papyrus.diagram.common.groups.groupcontainment&quot;
+ name=&quot;ActivityGroup&quot;
+ id=&quot;org.eclipse.papyrus.diagram.activity.activitygroup&quot;&gt;
+ &lt;modelContainer editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.StructuredActivityNodeStructuredActivityNodeContentCompartmentEditPart&quot; descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.StructuredActivityNodeContainment&quot;/&gt;
+ &lt;modelContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.ConditionalNodeContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.ConditionalNodeStructuredActivityNodeContentCompartmentEditPart&quot;&gt;
+ &lt;/modelContainer&gt;
+ &lt;modelContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.ExpansionRegionContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.ExpansionRegionStructuredActivityNodeContentCompartmentEditPart&quot;&gt;
+ &lt;/modelContainer&gt;
+ &lt;modelContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.LoopNodeContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.LoopNodeStructuredActivityNodeContentCompartmentEditPart&quot;&gt;
+ &lt;/modelContainer&gt;
+ &lt;modelContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.SequenceNodeContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.SequenceNodeStructuredActivityNodeContentCompartmentEditPart&quot;&gt;
+ &lt;/modelContainer&gt;
+ &lt;referenceContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.InterruptibleActivityRegionContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentEditPart&quot;/&gt;
+ &lt;referenceContainer descriptor=&quot;org.eclipse.papyrus.diagram.activity.groupcontainment.ActivityPartitionContainment&quot; editPartType=&quot;org.eclipse.papyrus.diagram.activity.edit.parts.ActivityPartitionActivityPartitionContentCompartmentEditPart&quot;/&gt;
+&lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ The interface org.eclipse.papyrus.diagram.common.groups.groupcontainment.IContainerNodeDescriptor must be implemented by classes used in the extensions.
+The interface org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart is used as it is supposed to be implemented by all edit parts in Papyrus.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ The activity diagram provides an extension for this extension point.
+Its usage is described in the example, taken from the org.eclipse.papyrus.diagram.activity plugin.
+
+In this case, all ActivityGroup elements are described :
+ - The StructuredActivityNode and inheriting classes are described by modelContainer nodes. For convenience, the descriptors inherit from a single one.
+ - The InterruptibleActivityRegion are described by a referenceContainer with the InterruptibleActivityRegionContainment class, for the corresponding edit part class.
+ - The ActivityPartition are described by a referenceContainer with the ActivityPartitionDescriptor class, for the corresponding edit part class.
+ </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/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Activator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Activator.java
new file mode 100644
index 00000000000..f3d7ffb6c81
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Activator.java
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * 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.diagram.common.groups;
+
+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.diagram.common.groups"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ 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/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Messages.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Messages.java
new file mode 100644
index 00000000000..088164099d9
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/Messages.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * 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.diagram.common.groups;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * The class handling messages for the group framework
+ */
+public class Messages extends NLS {
+
+
+ /**
+ * Initialize from files
+ */
+ static {
+ NLS.initializeMessages("messages", Messages.class); //$NON-NLS-1$
+ }
+
+ /**
+ * Private constructor
+ */
+ private Messages() {
+ }
+
+ /**
+ * Main message in ChooseElementsCreator
+ */
+ public static String ChooseContainedElementsCreator_Message;
+
+ /**
+ * Message to check/uncheck all checkboxes in ChooseElementsCreator
+ */
+ public static String ChooseContainedElementsCreator_CheckAll;
+
+ /**
+ * Message to run the action in ChooseContainedElementsCreator
+ */
+ public static String ChooseContainedElementsCreator_Run;
+
+ /**
+ * Main message in ChooseContainingGroupCreator
+ */
+ public static String ChooseContainingGroupCreator_Message;
+
+ /**
+ * Message to introduce a contained element in ChooseContainingGroupCreator
+ */
+ public static String ChooseContainingGroupCreator_Contained;
+
+ /**
+ * Message to run the action in ChooseContainingGroupCreator
+ */
+ public static String ChooseContainingGroupCreator_Run;
+
+ /**
+ * Message displayed when the user is asked to choose between graphical parents
+ */
+ public static String ChooseParentNotificationCommand_ChooseGraphicalParent;
+
+ /**
+ * Message display on the Choose graphical children notification
+ * e.g "Change graphical parent"
+ */
+ public static String ChooseParentNotificationCommand_ChooseGraphicalParentMessage;
+
+ /**
+ * Label of the Choose Children Notification
+ */
+ public static String ChooseChildrenICompositeCreator_ChooseChildren;
+
+ /**
+ * Message display to choose graphical children
+ */
+ public static String ChooseParentNotificationCommand_ChooseGraphicalChildrenMessage;
+
+ /**
+ * Message displayed when the user is asked to choose between model parents (This message is a warnig)
+ */
+ public static String ChooseParentNotificationCommand_ChooseModelParent;
+
+ /**
+ * Command label of HandleGraphicalChildrenMovingOut
+ */
+ public static String CommandsUtils_HandleGraphicalChildrenMovingOut_Label;
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeGraphicalParentCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeGraphicalParentCommand.java
new file mode 100644
index 00000000000..c6f45bb8b44
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeGraphicalParentCommand.java
@@ -0,0 +1,476 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gef.requests.CreateRequest;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.notation.LayoutConstraint;
+import org.eclipse.gmf.runtime.notation.Location;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.diagram.common.groups.edit.policies.XYLayoutEditGroupPolicy;
+import org.eclipse.papyrus.diagram.common.groups.utils.GroupRequestConstants;
+
+/**
+ * This command change the graphical parent of an edit part without changing the absolute position of the element
+ *
+ * @author arthur daussy
+ *
+ */
+public class ChangeGraphicalParentCommand extends AbstractTransactionalCommand {
+
+ public enum Mode {
+ /**
+ * Case when the parent is in creation.
+ */
+ CREATION_PARENT,
+ /**
+ * Case when the child is in creation
+ */
+ CREATION_CHILD,
+ /**
+ * Case when the child is moving (ChangeBoundsRequest)
+ */
+ MOVE_CHILD,
+ /**
+ * case when the parent is moving
+ */
+ MOVE_PARENT,
+ /**
+ * Case when there is no need of a request. All elements has been placed annd all element ared fixed
+ */
+ NORMAL
+ }
+
+
+ /** child part */
+ private EditPart child;
+
+ /** parent part */
+ private EditPart parent;
+
+ private Request request;
+
+ private IGraphicalEditPart host;
+
+ /**
+ * Current mode @see #mode
+ */
+ private Mode mode;
+
+
+
+ /**
+ *
+ * Command constructor.
+ * Create a command from to existing EditPart which exist at the time of the creation of the command
+ *
+ * @param domain
+ * editing domain
+ * @param label
+ * command label
+ * @param parent
+ * new parent edit part
+ * @param child
+ * child edit part to reroute parent
+ */
+ public ChangeGraphicalParentCommand(TransactionalEditingDomain domain, String label, EditPart parent, EditPart child, IGraphicalEditPart getHost) {
+ super(domain, label, null);
+ this.parent = parent;
+ this.child = child;
+ this.request = null;
+ this.host = getHost;
+ this.mode = Mode.NORMAL;
+ }
+
+ /**
+ *
+ * Command constructor.
+ * Create a command from to existing EditPart which exist at the time of the creation of the command.
+ * In this constructor the request is needed if any translation has to be made (e.g {@link ChangeBoundsRequest} @see
+ * {@link XYLayoutEditGroupPolicy#getCommand(Request)}
+ *
+ * @param domain
+ * editing domain
+ * @param label
+ * command label
+ * @param parent
+ * new parent edit part
+ * @param child
+ * child edit part to reroute parent
+ */
+ public ChangeGraphicalParentCommand(TransactionalEditingDomain domain, String label, EditPart parent, EditPart child, IGraphicalEditPart getHost, Request request) {
+ super(domain, label, null);
+ this.parent = parent;
+ this.child = child;
+ this.request = request;
+ this.host = getHost;
+ this.mode = Mode.MOVE_PARENT;
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * editing domain
+ * @param label
+ * command label
+ * @param request
+ * Create element request to be able to find the IGraphicalEditPart of the create element
+ * ( WARNING the IGraphicalEditPart has to be already created at the execution time of this command and it has to be have it's bounds set)
+ * @param child
+ * IGraphicalEditPart of the child (has to be available a the creation time of the request)
+ */
+ public ChangeGraphicalParentCommand(TransactionalEditingDomain domain, String label, CreateRequest request, EditPart child, IGraphicalEditPart getHost) {
+ super(domain, label, null);
+ this.parent = null;
+ this.child = child;
+ this.request = (CreateViewAndElementRequest)request;
+ this.host = getHost;
+ this.mode = Mode.CREATION_PARENT;
+ }
+
+ /**
+ * This command change the view of the parent and the child edit part to make all the changes needed.
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
+ * org.eclipse.core.runtime.IAdaptable)
+ */
+ protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
+ //Get the IGraphical edit part of the old parent
+ IGraphicalEditPart oldParentPart = (IGraphicalEditPart)child.getParent();
+ Map<?, ?> editPartRegistry = getEditPartRegistery();
+ if(editPartRegistry == null) {
+ return CommandResult.newErrorCommandResult(CommandResultMessagesError.THE_EDIT_PART_REGISTERY_WAS_NOT_FOUND);
+ }
+ //Get the view of the new parent, old parent and the child
+ // If the parent is null then check if the request is an creation request
+ if(parent == null) {
+ if(request instanceof CreateViewAndElementRequest) {
+ //If true try to get the EditPart of the element in creation
+ parent = getEditPartFromViewDescriptor((IGraphicalEditPart)child, (CreateViewAndElementRequest)request);
+ }
+ } else {
+ parent = Utils.getCompartementEditPartFromMainEditPart(editPartRegistry, parent);
+ }
+ if(parent == null) {
+ //If no parent is found then an error is thrown
+ return CommandResult.newErrorCommandResult(CommandResultMessagesError.IGRAPHICAL_EDIT_PART_NOT_CREATED_YET);
+ }
+ View newParentView = (View)parent.getModel();
+ View childView = (View)child.getModel();
+ /*
+ * Translate the new node to the corresponding location in its new father.
+ */
+ CommandResult cmdChangeCoordinate = changeCoordinateInNewFather(oldParentPart, childView);
+ if(cmdChangeCoordinate != null) {
+ return cmdChangeCoordinate;
+ }
+ newParentView.insertChild(childView);
+ return CommandResult.newOKCommandResult();
+ }
+
+ /**
+ * This method will change the coordinate of the element on which we are changing it's parent.
+ * This method is not generic. It will handle differently if the command is came from a createRequest or the cahgneBounds request or without any
+ * request.
+ * This method should be reviewed later.(TODO)
+ *
+ * @param oldParentPart
+ * {@link IGraphicalEditPart} of the old paret
+ * @param childView
+ * View of the child
+ * @return
+ */
+ private CommandResult changeCoordinateInNewFather(IGraphicalEditPart oldParentPart, View childView) {
+ /*
+ * Deleted because do not find the case where should it should be applied
+ * if(host != parent) {
+ */
+ if(childView instanceof Node) {
+ IFigure parentCompartmentFigure = ((AbstractGraphicalEditPart)parent).getFigure();
+ /*
+ * If the change graphical parent come after a move
+ */
+ if(Mode.MOVE_CHILD.equals(mode) || Mode.MOVE_PARENT.equals(mode)) {
+ Rectangle newDimension = computeDeltaToChangeParent((IGraphicalEditPart)parent);
+ LayoutConstraint layoutConstraint = ((Node)childView).getLayoutConstraint();
+ if(layoutConstraint instanceof Location) {
+ Location location = (Location)layoutConstraint;
+ location.setX(newDimension.x);
+ location.setY(newDimension.y);
+ } else {
+ return CommandResult.newErrorCommandResult("The layoutConstraint is not an instance of Location");
+ }
+ /*
+ * If the change come after a creation or after nothing
+ */
+ } else if(Mode.CREATION_CHILD.equals(mode) || Mode.CREATION_PARENT.equals(mode) || Mode.NORMAL.equals(mode)) {
+ /*
+ * Handle change graphical parent from a create request or with no request
+ * 1 - If the group in creation is the parent then
+ * 1.1 Used the Hack to force the figure to draw (in order to have it's position)
+ * 2 - Compute delta from computeDeltaToChangeParent
+ * 3 - Translate the location of the constraint
+ */
+ Dimension newDimension;
+ if(parentCompartmentFigure.getBounds().isEmpty()) {
+ Rectangle oldBounds = parentCompartmentFigure.getBounds().getCopy();
+ Point compLoc = emulateFigureCreation(parentCompartmentFigure);
+ newDimension = Utils.computeDeltaToChangeParent(oldParentPart, (IGraphicalEditPart)parent.getParent());
+ reajustNewDimensionIfNeeded(parentCompartmentFigure, compLoc, newDimension);
+ parentCompartmentFigure.getBounds().setBounds(oldBounds);
+ } else {
+ newDimension = Utils.computeDeltaToChangeParent(oldParentPart, (IGraphicalEditPart)parent);
+ }
+ LayoutConstraint layoutConstraint = ((Node)childView).getLayoutConstraint();
+ if(layoutConstraint instanceof Location) {
+ Location location = (Location)layoutConstraint;
+ Point newLocation = new Point(newDimension.width + location.getX(), newDimension.height + location.getY());
+ location.setX(newLocation.x);
+ location.setY(newLocation.y);
+ } else {
+ return CommandResult.newErrorCommandResult("The layoutConstraint is not an instance of Location");
+ }
+ }
+
+ } else {
+ /*
+ * Error in group framework usage
+ */
+ return CommandResult.newErrorCommandResult("The new containing edit part should be compartment node. The extension point org.eclipse.papyrus.diagram.common.groups.groupcontainment may have been incorrectly used.");
+ }
+ return null;
+ }
+
+ /**
+ * Compute the new rectangle of the child from the original position set in the request and with the newParent {@link IGraphicalEditPart}
+ *
+ * @param newParent
+ * {@link IGraphicalEditPart} of the new parent
+ * @return new rectangle of the child
+ */
+ private Rectangle computeDeltaToChangeParent(IGraphicalEditPart newParent) {
+ /*
+ * Get the absolute bound of a child
+ */
+ Rectangle childAbsoluteRectangle = getChildAbsoluteBounds();
+ if(childAbsoluteRectangle instanceof Rectangle) {
+ IFigure newPartFigure = ((IGraphicalEditPart)parent).getContentPane();
+ newPartFigure.translateToRelative(childAbsoluteRectangle);
+ newPartFigure.translateFromParent(childAbsoluteRectangle);
+ Point negatedLayoutOrigin = newPartFigure.getClientArea().getLocation().getNegated();
+ childAbsoluteRectangle.performTranslate(negatedLayoutOrigin.x, negatedLayoutOrigin.y);
+ /*
+ * Correct the position of the child in the parent if any @see getChildCorrectionFromParent
+ */
+ Point negatedMoved = getChildCorrectionFromParent();
+ childAbsoluteRectangle.performTranslate(negatedMoved.x, negatedMoved.y);
+ return childAbsoluteRectangle;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the EditpartRegistery
+ *
+ * @return Map if found null is not found
+ */
+ private Map<?, ?> getEditPartRegistery() {
+ Map<?, ?> editPartRegistry = null;
+ //Check if the parent in valid compartment EditPart
+ if(parent != null) {
+ EditPartViewer parentViewer = parent.getViewer();
+ if(parentViewer != null) {
+ editPartRegistry = parentViewer.getEditPartRegistry();
+ }
+ }
+ if(editPartRegistry == null && child != null && child.getViewer() != null) {
+ editPartRegistry = child.getViewer().getEditPartRegistry();
+ }
+ return editPartRegistry;
+ }
+
+
+ /**
+ * Used to readjusts the coordinate of the child if the parentComptmentFigure is not well set yet.
+ * Used to hack the system if the editPart is not properly set
+ *
+ * @param parentCompartmentFigure
+ * The compartment figure of the parent
+ * @param compLoc
+ * @see {@link #emulateFigureCreation(IFigure)}
+ * @param correctionDimension
+ * New {@link Dimension} which are going to modify in order to correctt the coordinatte of the child
+ */
+ private void reajustNewDimensionIfNeeded(IFigure parentCompartmentFigure, Point compLoc, Dimension correctionDimension) {
+ if(compLoc != null) {
+ correctionDimension.shrink(compLoc.x + parentCompartmentFigure.getInsets().left, compLoc.y + parentCompartmentFigure.getInsets().top);
+ }
+ }
+
+ /**
+ * Emulate the figure creation it's not already done. This allow the system to know the absolute solution even if the edit part of the parent is
+ * not yet finish
+ *
+ * @return null is the figure is already done. Return the translation needed to take into account the child position in it's parent ( e.g
+ * ActivityPartitionCompartement from its ActivityPartitionEditPart)
+ */
+ private Point emulateFigureCreation(IFigure parentCompartmentFigure) {
+ if(parentCompartmentFigure.getBounds().isEmpty()) {
+ // layout parent node correctly to recover the correct location of compartment which has not been set previously
+ IFigure parentNodeFigure = parentCompartmentFigure.getParent();
+ if(parentNodeFigure != null) {
+ IFigure grandParentFigure = parentNodeFigure.getParent();
+ if(grandParentFigure != null) {
+ grandParentFigure.getLayoutManager().layout(grandParentFigure);
+ }
+ parentNodeFigure.getLayoutManager().layout(parentNodeFigure);
+ }
+ Point compLoc = parentCompartmentFigure.getBounds().getLocation();
+ return compLoc;
+ }
+ return null;
+
+ }
+
+ /**
+ * This method is going to get the edit part from the request.
+ * 1 - Get descriptors
+ * 2 - Get View (adapter)
+ * 3 - Get IGraphicalEditPart if it exists
+ *
+ * @param anyPart
+ * Any IGraphicalEditPart in order to get the EditPartRegistery
+ * @return true if it as found the edit part
+ */
+ private EditPart getEditPartFromViewDescriptor(IGraphicalEditPart anyPart, CreateViewAndElementRequest _request) {
+
+ EditPart result = null;
+ Iterator<? extends CreateViewRequest.ViewDescriptor> descriptors = _request.getViewDescriptors().iterator();
+ Map<?, ?> editPartRegistry = anyPart.getViewer().getEditPartRegistry();
+ while(descriptors.hasNext()) {
+ CreateViewRequest.ViewDescriptor descriptor = (CreateViewRequest.ViewDescriptor)descriptors.next();
+ Object view = descriptor.getAdapter(View.class);
+ if(view instanceof View) {
+ View childView = (View)view;
+ result = getCompartmentEditPartFromView(editPartRegistry, childView);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get a compartment editPart from a view and the editPartRegistery
+ *
+ * @param editPartRegistry
+ * EditPartRegistery
+ * @param view
+ * View of the element we want to find the compartment
+ * @return the EdiPart of compartment and null if not found
+ */
+ public EditPart getCompartmentEditPartFromView(Map<?, ?> editPartRegistry, View view) {
+ EditPart resultCompartmentEditPart = null;
+ Object editPartAux = editPartRegistry.get(view);
+ if(editPartAux instanceof EditPart) {
+ EditPart _editPart = (EditPart)editPartAux;
+ resultCompartmentEditPart = Utils.getCompartementEditPartFromMainEditPart(editPartRegistry, _editPart);
+ }
+ return resultCompartmentEditPart;
+ }
+
+
+
+ public Mode getMode() {
+ return mode;
+ }
+
+
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Give the absolute rectangle of the child. (Depending of the mode)
+ *
+ * @return {@link Rectangle} of the child
+ */
+ private Rectangle getChildAbsoluteBounds() {
+ Rectangle result = null;
+ if(child instanceof IGraphicalEditPart) {
+ switch(mode) {
+ case MOVE_CHILD:
+ if(request instanceof ChangeBoundsRequest) {
+ Object _origineConstraint = request.getExtendedData().get(GroupRequestConstants.CONSTRAINT_AFTER_MOVING);
+ if(_origineConstraint instanceof Rectangle) {
+ result = (Rectangle)_origineConstraint;
+ }
+ }
+ break;
+ case MOVE_PARENT:
+ result = Utils.getAbsoluteBounds((IGraphicalEditPart)child).getCopy();
+ break;
+ default:
+ result = Utils.getAbsoluteBounds((IGraphicalEditPart)child).getCopy();
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the correction to be applied to the child in function of the mode
+ *
+ * @return {@link Point} to translate the child
+ */
+ private Point getChildCorrectionFromParent() {
+ Point result = null;
+ if(child instanceof IGraphicalEditPart) {
+ switch(mode) {
+ case MOVE_PARENT:
+ result = ((ChangeBoundsRequest)request).getMoveDelta().getNegated();
+ break;
+ default:
+ result = new Point(0, 0);
+ break;
+ }
+ }
+ return result;
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeModelParentCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeModelParentCommand.java
new file mode 100644
index 00000000000..20096f93a25
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChangeModelParentCommand.java
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
+import org.eclipse.gmf.runtime.emf.type.core.internal.l10n.EMFTypeCoreMessages;
+
+/**
+ * This command will change the model parent of child to the IAdaptable parent.
+ *
+ * @author adaussy
+ *
+ */
+public class ChangeModelParentCommand extends AbstractTransactionalCommand {
+
+ /**
+ * Child to add to the IAdaptable parent
+ */
+ private Map<EObject, EReference> chilrendToMove;
+
+ private EObject targetContainer;
+
+ private IAdaptable elementAdapter;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * @param parentGroupAdapter
+ * @param chilrendToMove
+ * @param anyPart
+ * @param groupDescriptor
+ */
+ public ChangeModelParentCommand(TransactionalEditingDomain domain, IAdaptable parentGroupAdapter, Map<EObject, EReference> chilrendToMove, IGraphicalEditPart anyPart) {
+ super(domain, "Change model parent command", null);
+ this.chilrendToMove = chilrendToMove;
+ this.elementAdapter = parentGroupAdapter;
+ targetContainer = null;
+ // if(anyPart != null) {
+ // this.editPartRegistery = anyPart.getViewer().getEditPartRegistry();
+ // }
+
+ }
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
+ if(targetContainer == null) {
+ Object group = elementAdapter.getAdapter(EObject.class);
+ if(group instanceof EObject) {
+ targetContainer = (EObject)group;
+ }
+ }
+ if(targetContainer == null) {
+ return CommandResult.newErrorCommandResult("Unable to change the model parent of the object because the system was enable to find the EObject of the parent group");
+ }
+
+ for(Iterator<EObject> i = getElementsToMove().keySet().iterator(); i.hasNext();) {
+ EObject element = (EObject)i.next();
+ EReference feature = getTargetFeature(element);
+ if(feature != null && targetContainer.eClass().getEAllReferences().contains(feature)) {
+ if(feature.isMany()) {
+ @SuppressWarnings("rawtypes")
+ Collection coll = (Collection)targetContainer.eGet(feature);
+ coll.add(element);
+ } else {
+ targetContainer.eSet(feature, element);
+ }
+ } else {
+ return CommandResult.newErrorCommandResult(EMFTypeCoreMessages.moveElementsCommand_noTargetFeature);
+ }
+ }
+
+ return CommandResult.newOKCommandResult();
+ }
+
+ private Map<EObject, EReference> getElementsToMove() {
+ return chilrendToMove;
+ }
+
+ protected EReference getTargetFeature(EObject element) {
+ EReference feature = (EReference)getElementsToMove().get(element);
+ if(feature == null) {
+ EReference oldContainmentFeature = element.eContainmentFeature();
+ if(getTargetContainer().eClass().getEAllReferences().contains(oldContainmentFeature)) {
+ getElementsToMove().put(element, oldContainmentFeature);
+ feature = oldContainmentFeature;
+ }
+ }
+ if(feature == null) {
+ feature = PackageUtil.findFeature(getTargetContainer().eClass(), element.eClass());
+ setTargetFeature(element, feature);
+ }
+
+ return feature;
+ }
+
+ private EObject getTargetContainer() {
+ return targetContainer;
+ }
+
+ protected void setTargetFeature(EObject element, EReference targetFeature) {
+ getElementsToMove().put(element, targetFeature);
+ }
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseChildrenNotificationCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseChildrenNotificationCommand.java
new file mode 100644
index 00000000000..dff860e6036
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseChildrenNotificationCommand.java
@@ -0,0 +1,214 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.ChooseChildrenNotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.NotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.util.DiagramEditPartsUtil;
+
+/**
+ * This command will create a notification to ask the user to choose the graphical children of an element
+ *
+ * @author arthur daussy
+ *
+ */
+public class ChooseChildrenNotificationCommand extends AbstractTransactionalCommand {
+
+ /**
+ * All possible graphical children
+ */
+ private List<IGraphicalEditPart> allChildren;
+
+ /**
+ * All children which are automatically chosen as graphical child
+ */
+ private List<IGraphicalEditPart> automaticChildren;
+
+ /**
+ * {@link IAdaptable} of the view (used to retrieve the {@link EditPart})
+ */
+ private IAdaptable adapter;
+
+ /**
+ * {@link EditPart} on which we have to choose the graphical children
+ */
+ private IGraphicalEditPart mainEditPart;
+
+
+ /**
+ * {@link EditPart} hosting the {@link EditPolicy}
+ */
+ private IGraphicalEditPart host;
+
+ /**
+ * Pending Group manager
+ */
+ private PendingGroupNotificationsManager manager;
+
+ /**
+ * List of all notification created and modifed
+ */
+ private List<ChooseChildrenNotificationConfigurator> createdNotificationConfigurator;
+
+ /**
+ * {@link DiagramEditPart}
+ */
+ private DiagramEditPart diagramPart;
+
+ /**
+ * Construct the command for asking to choose graphical children of a adapter
+ * Constructor.
+ *
+ * @param domain
+ * @see {@link AbstractTransactionalCommand}
+ * @param label
+ * @see {@link AbstractTransactionalCommand}
+ * @param _allChildren
+ * @see {@link #allChildren}
+ * @param _automaticChildren
+ * @see {@link #automaticChildren}
+ * @param _adapter
+ * @see {@link #adapter}
+ */
+ public ChooseChildrenNotificationCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> _allChildren, List<IGraphicalEditPart> _automaticChildren, IAdaptable _adapter, IGraphicalEditPart getHost, DiagramEditPart _diagramPart) {
+ super(domain, label, null);
+ this.allChildren = _allChildren;
+ this.automaticChildren = _automaticChildren;
+ this.adapter = _adapter;
+ this.host = getHost;
+ this.diagramPart = _diagramPart;
+ this.manager = PendingGroupNotificationsManager.getInstanceForDiagram(DiagramEditPartsUtil.getDiagramEditPart(getHost));
+ }
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ if(!getEditPartFromEditPartAdapter()) {
+ if(!allChildren.isEmpty()) {
+ getEditPartFromViewAdapter(allChildren.get(0));
+ }
+ }
+ if(mainEditPart != null) {
+ createdNotificationConfigurator = new ArrayList<ChooseChildrenNotificationConfigurator>();
+ NotificationConfigurator configurator = PendingGroupNotificationsManager.getInstanceForDiagram(diagramPart).getChooseChildrenPendingNotification(mainEditPart);
+ ChooseChildrenNotificationConfigurator notificationConfigurator = null;
+ if(configurator == null) {
+ //If there is no a pending notification for this main edit part then it create one
+ if(!allChildren.isEmpty() && isChildrenToChoose()) {
+ notificationConfigurator = new ChooseChildrenNotificationConfigurator(mainEditPart, allChildren, automaticChildren, host, manager);
+ notificationConfigurator.runConfigurator();
+ }
+ } else {
+ //Else update the old one if needed TODO TODO
+ // 1 - Compare if there is any modification TODO
+ if(configurator instanceof ChooseChildrenNotificationConfigurator) {
+ notificationConfigurator = (ChooseChildrenNotificationConfigurator)configurator;
+ if(notificationConfigurator.isThereAnyModification(mainEditPart, allChildren, automaticChildren, host)) {
+ // 2 - There are some update the old notification TODO
+ notificationConfigurator.closeNotification();
+ if(!allChildren.isEmpty() && isChildrenToChoose()) {
+ notificationConfigurator = new ChooseChildrenNotificationConfigurator(mainEditPart, allChildren, automaticChildren, host, manager);
+ notificationConfigurator.runConfigurator();
+ }
+
+ }
+ }
+ }
+ if(notificationConfigurator != null) {
+ createdNotificationConfigurator.add(notificationConfigurator);
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ return CommandResult.newErrorCommandResult("The editPart of the adaptable element has not been found");//$NON-NLS-1$
+ }
+
+ /**
+ * Return true if there is some children on which the user should choose the graphical parent
+ *
+ * @return
+ */
+ private boolean isChildrenToChoose() {
+ return (allChildren.size() > automaticChildren.size());
+ }
+
+ /**
+ * Set the main edit part attribute from the adapter
+ *
+ * @param any
+ * Any {@link IGraphicalEditPart} from which we can get the EditPartRegistery
+ * @return true if succeed
+ */
+ private Boolean getEditPartFromEditPartAdapter() {
+ Object _mainEditPart = adapter.getAdapter(EditPart.class);
+ if(_mainEditPart instanceof IGraphicalEditPart) {
+ mainEditPart = (IGraphicalEditPart)_mainEditPart;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get the {@link IGraphicalEditPart} from view adapter
+ *
+ * @param any
+ * @return
+ */
+ private Boolean getEditPartFromViewAdapter(IGraphicalEditPart any) {
+ Object view = adapter.getAdapter(View.class);
+ Map<?, ?> registery = any.getViewer().getEditPartRegistry();
+ if(view instanceof View) {
+ View childView = (View)view;
+ Object auxPart = registery.get(childView);
+ if(auxPart instanceof IGraphicalEditPart) {
+ mainEditPart = (IGraphicalEditPart)auxPart;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Inform that the command has been undone and delete or update the created notification
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#didUndo(org.eclipse.emf.transaction.Transaction)
+ * @param tx
+ * a transaction that has been undone.
+ */
+ @Override
+ protected void didUndo(Transaction tx) {
+ for(ChooseChildrenNotificationConfigurator notifConfigurator : createdNotificationConfigurator) {
+ notifConfigurator.closeNotification();
+ }
+ super.didUndo(tx);
+
+
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseParentNotificationCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseParentNotificationCommand.java
new file mode 100644
index 00000000000..d64ad9d2063
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/ChooseParentNotificationCommand.java
@@ -0,0 +1,219 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.Messages;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.ChooseParentNotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.NotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.groups.utils.GroupRequestConstants;
+import org.eclipse.papyrus.diagram.common.util.DiagramEditPartsUtil;
+
+/**
+ * Command to display the notification for choosing parent.
+ * This command handle two modes:
+ *
+ * @see #GRAPHICAL_MODE : Display the notification in order to choose the graphical parent
+ * @see #MODEL_MODE : Display the warning in order to choose the model parent and change automatically the graphical parent
+ * @author arthur daussy
+ */
+public class ChooseParentNotificationCommand extends AbstractTransactionalCommand {
+
+ /** mode for graphical parent */
+ public static final boolean GRAPHICAL_MODE = true;
+
+ /** mode for model parent */
+ public static final boolean MODEL_MODE = false;
+
+ /** the mode to use this command with */
+ private boolean mode;
+
+ /** list of possible parent parts */
+ private List<IGraphicalEditPart> parents;
+
+ /** child part to choose parent for */
+ private IGraphicalEditPart childEditPart;
+
+ /** creation request */
+ private Request request;
+
+ /** EditPart of host of the {@link EditPolicy} */
+ private IGraphicalEditPart host;
+
+ /**
+ * Manage of the pending notification
+ */
+ private PendingGroupNotificationsManager manager;
+
+ /**
+ * {@link NotificationConfigurator} of the pointed childEditPart
+ */
+ private ChooseParentNotificationConfigurator notifConfigurator;
+
+
+ /**
+ * Constructor for element creation.
+ *
+ * @param domain
+ * editing domain
+ * @param label
+ * command label
+ * @param parents
+ * possible parents
+ * @param request
+ * creation request
+ */
+ public ChooseParentNotificationCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> parents, Request request, Boolean mode, IGraphicalEditPart getHost) {
+ super(domain, label, null);
+ this.parents = parents;
+ this.request = request;
+ this.mode = mode;
+ this.host = getHost;
+ this.manager = PendingGroupNotificationsManager.getInstanceForDiagram(DiagramEditPartsUtil.getDiagramEditPart(getHost));
+ }
+
+
+
+
+
+ /**
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
+ * org.eclipse.core.runtime.IAdaptable)
+ */
+ protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
+ if(parents != null) {
+ if(getEditPartFromDescriptor()) {
+ String label;
+ ChooseParentNotificationConfigurator configurator = null;
+ if(mode == GRAPHICAL_MODE) {
+ label = new String(Messages.ChooseParentNotificationCommand_ChooseGraphicalParent);
+ configurator = new ChooseParentNotificationConfigurator(parents, childEditPart, mode, host, manager, NotificationConfigurator.Mode.QUESTION_MODE, label);
+ } else {
+ label = new String(Messages.ChooseParentNotificationCommand_ChooseGraphicalParent);
+ configurator = new ChooseParentNotificationConfigurator(parents, childEditPart, mode, host, manager, NotificationConfigurator.Mode.WARNING_MODE, label);
+ }
+ if(configurator != null) {
+ notifConfigurator = configurator;
+ configurator.runConfigurator();
+ return CommandResult.newOKCommandResult();
+ }
+ }
+ }
+ return CommandResult.newErrorCommandResult(GroupRequestConstants.CHOOSE_PARENT_ERROR_NOTIFICATION);
+
+
+ }
+
+ /**
+ * This method is going to get the edit part from the request.
+ * 1 - Get descriptors
+ * 2 - Get View (adapter)
+ * 3 - Get IGraphicalEditPart if it exist
+ *
+ * @return true if it as found the edit part
+ */
+ private Boolean getEditPartFromDescriptor() {
+ if(request instanceof CreateViewAndElementRequest) {
+ CreateViewAndElementRequest createRequest = (CreateViewAndElementRequest)request;
+ Iterator<? extends CreateViewRequest.ViewDescriptor> descriptors = createRequest.getViewDescriptors().iterator();
+ while(descriptors.hasNext()) {
+ CreateViewRequest.ViewDescriptor descriptor = (CreateViewRequest.ViewDescriptor)descriptors.next();
+ Object view = descriptor.getAdapter(View.class);
+ if(view instanceof View) {
+ View childView = (View)view;
+ if(!parents.isEmpty()) {
+ Object childEditPartAux = parents.get(0).getViewer().getEditPartRegistry().get(childView);
+ if(childEditPartAux instanceof IGraphicalEditPart) {
+ childEditPart = (IGraphicalEditPart)childEditPartAux;
+ }
+ }
+ }
+ }
+ } else if(request instanceof ChangeBoundsRequest) {
+ ChangeBoundsRequest changeBoundsRequest = (ChangeBoundsRequest)request;
+ if(!changeBoundsRequest.getEditParts().isEmpty()) {
+ Object editPart = changeBoundsRequest.getEditParts().get(0);
+ if(editPart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart _childEditPart = (IGraphicalEditPart)editPart;
+ View childView = _childEditPart.getNotationView();
+ if(!parents.isEmpty()) {
+ Object childEditPartAux = parents.get(0).getViewer().getEditPartRegistry().get(childView);
+ if(childEditPartAux instanceof IGraphicalEditPart) {
+ childEditPart = (IGraphicalEditPart)childEditPartAux;
+ }
+ }
+
+ }
+ }
+ }
+ if(childEditPart != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Set the list of possible parents
+ *
+ * @param parents
+ * list of possible parents
+ */
+ public void setListOfParents(List<IGraphicalEditPart> parents) {
+ this.parents = parents;
+ }
+
+ /**
+ * Set mode to use this command
+ *
+ * @param mode
+ * one of {@link #GRAPHICAL_MODE} or {@link #MODEL_MODE}
+ */
+ public void setMode(boolean mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Inform that the command has been undone and delete or update the created notification
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#didUndo(org.eclipse.emf.transaction.Transaction)
+ * @param tx
+ * a transaction that has been undone.
+ */
+ @Override
+ protected void didUndo(Transaction tx) {
+ if(notifConfigurator != null) {
+ notifConfigurator.closeNotification();
+ }
+ super.didUndo(tx);
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/CommandResultMessagesError.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/CommandResultMessagesError.java
new file mode 100644
index 00000000000..52f70d5b413
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/CommandResultMessagesError.java
@@ -0,0 +1,10 @@
+package org.eclipse.papyrus.diagram.common.groups.commands;
+
+
+public class CommandResultMessagesError {
+
+ static final String IGRAPHICAL_EDIT_PART_NOT_CREATED_YET = "The IGraphicalEditPart of the parent is not created yet";
+
+ public static final String THE_EDIT_PART_REGISTERY_WAS_NOT_FOUND = "The EditPartRegistery was not found";
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/SetUpReferencesCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/SetUpReferencesCommand.java
new file mode 100644
index 00000000000..8b855e90bad
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/SetUpReferencesCommand.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+
+/**
+ * Command to update referencing groups for a child element.
+ * (The child element is not necessary already created, it has just to be available through an adapter at runtime execution).
+ *
+ * @author arthur daussy
+ */
+public class SetUpReferencesCommand extends AbstractTransactionalCommand {
+
+ private IAdaptable elementAdapter;
+
+ private List<IGraphicalEditPart> graphicalParent;
+
+
+ /**
+ * Command constructor
+ *
+ * @param domain
+ * editing domain
+ * @param label
+ * command label
+ * @param adapter
+ * adapter to recover created element
+ */
+ public SetUpReferencesCommand(TransactionalEditingDomain domain, String label, IAdaptable adapter, List<IGraphicalEditPart> _graphicalParents) {
+ super(domain, label, null);
+ elementAdapter = adapter;
+ this.graphicalParent = _graphicalParents;
+ }
+
+ /**
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
+ * org.eclipse.core.runtime.IAdaptable)
+ *
+ * @param arg0
+ * @param arg1
+ * @return
+ * @throws ExecutionException
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
+ Object createdElement = elementAdapter.getAdapter(EObject.class);
+ if(createdElement instanceof EObject) {
+ EObject eObjectCreatedElement = (EObject)createdElement;
+ for(IGraphicalEditPart parent : graphicalParent) {
+ EObject eObjectSourceReference = parent.resolveSemanticElement();
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(parent);
+ List<EReference> refs = desc.getReferenceFor(eObjectCreatedElement.eClass());
+ for(EReference ref : refs) {
+ if(ref != null && ref.isMany()) {
+ Collection<EObject> collection = (Collection<EObject>)eObjectSourceReference.eGet(ref);
+ if(!collection.contains(eObjectCreatedElement)) {
+ collection.add(eObjectCreatedElement);
+ }
+ } else if(ref != null && !ref.isMany()) {
+ eObjectSourceReference.eSet(ref, eObjectCreatedElement);
+ }
+ }
+
+ }
+
+ }
+
+ return CommandResult.newOKCommandResult();
+ }
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/UpdateReferencesCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/UpdateReferencesCommand.java
new file mode 100644
index 00000000000..68f46584c3f
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/UpdateReferencesCommand.java
@@ -0,0 +1,157 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+
+/**
+ * Update all references of a parent group.
+ * This class will set or unset references of the parent from a given child list
+ *
+ * @author arthur daussy
+ *
+ */
+
+public class UpdateReferencesCommand extends AbstractTransactionalCommand {
+
+ /**
+ * Mode used to set references
+ */
+ public final static boolean SET_MODE = true;
+
+ /**
+ * Mode used to unset references
+ */
+ public final static boolean UNSET_MODE = false;
+
+ /**
+ * List of all {@link IGraphicalEditPart} of all children
+ */
+ private List<IGraphicalEditPart> childrenPart;
+
+ /**
+ * {@link AbstractContainerNodeDescriptor} of the parent group
+ */
+ private AbstractContainerNodeDescriptor descriptor;
+
+ /**
+ * {@link IAdaptable} of the parent (Used to find {@link EObject}
+ */
+ private IAdaptable elementAdapter;
+
+ /**
+ * Current mode {@link UpdateReferencesCommand#UNSET_MODE} and {@link #SET_MODE}
+ */
+ private boolean setMode = true;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * @see {@link AbstractTransactionalCommand}
+ * @param label
+ * @see {@link AbstractTransactionalCommand}
+ * @param children
+ * @see {@link #childrenPart}
+ * @param descriptor
+ * @see {@link #descriptor}
+ * @param adapter
+ * @see {@link #elementAdapter}
+ */
+ public UpdateReferencesCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> children, AbstractContainerNodeDescriptor descriptor, IAdaptable adapter) {
+ super(domain, label, null);
+ this.descriptor = descriptor;
+ elementAdapter = adapter;
+ this.childrenPart = children;
+
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * @see {@link AbstractTransactionalCommand}
+ * @param label
+ * @see {@link AbstractTransactionalCommand}
+ * @param children
+ * @see {@link #childrenPart}
+ * @param descriptor
+ * @see {@link #descriptor}
+ * @param adapter
+ * @see {@link #elementAdapter}
+ */
+ public UpdateReferencesCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> children, AbstractContainerNodeDescriptor descriptor, IAdaptable adapter, boolean mode) {
+ super(domain, label, null);
+ this.descriptor = descriptor;
+ elementAdapter = adapter;
+ this.childrenPart = children;
+ this.setMode = mode;
+
+ }
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
+ Object createdElement = elementAdapter.getAdapter(EObject.class);
+ if(createdElement instanceof EObject) {
+ EObject eObjectCreatedElement = (EObject)createdElement;
+ for(IGraphicalEditPart part : childrenPart) {
+ EObject childElement = part.resolveSemanticElement();
+ List<EReference> refs = descriptor.getReferenceFor(childElement.eClass());
+ for(EReference ref : refs) {
+ //Add reference to the father
+ if(ref != null && ref.isMany()) {
+ //ref.getEOpposite()
+ Collection<EObject> collection = (Collection<EObject>)eObjectCreatedElement.eGet(ref);
+ if(setMode) {
+ if(!collection.contains(childElement)) {
+ collection.add(childElement);
+ }
+ } else {
+ if(collection.contains(childElement)) {
+ collection.remove(childElement);
+ }
+ }
+ //Remove all element which have a model sons in the collection
+ } else if(ref != null && !ref.isMany()) {
+ if(setMode) {
+ eObjectCreatedElement.eSet(ref, childElement);
+ } else {
+ eObjectCreatedElement.eUnset(ref);
+ }
+ }
+ }
+ Utils.withDrawRedundantElementReferenced(childElement);
+ }
+ }
+
+ return CommandResult.newOKCommandResult();
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/utlis/CommandsUtils.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/utlis/CommandsUtils.java
new file mode 100644
index 00000000000..c6096a43368
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/commands/utlis/CommandsUtils.java
@@ -0,0 +1,1172 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.commands.utlis;
+
+import java.util.ArrayList;
+import java.util.Collections;
+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.IAdaptable;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.Adaptable;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.SemanticCreateCommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.Messages;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand.Mode;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeModelParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChooseChildrenNotificationCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChooseParentNotificationCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.SetUpReferencesCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.UpdateReferencesCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.DefaultModelParent;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+import org.eclipse.papyrus.diagram.common.groups.utils.GroupRequestConstants;
+
+/**
+ * Util class for command
+ *
+ * @author arthur daussy
+ *
+ */
+public class CommandsUtils {
+
+ /**
+ * Parameter in a request which define which host (IGrapicalEditPart) has to handle the request
+ */
+ public static final String NEW_PARENT_HOST = "New_parent_host";
+
+ /**
+ * Parameter in a request which define the graphical parent ((IGrapicalEditPart))
+ */
+ public static final String GRAPHICAL_PARENT = "Graphical_parent";
+
+ /**
+ * Get the semantic command to create a new element.
+ * This will set ups all references needed and create the semantic Container Parent Command
+ *
+ * @param requestAdapter
+ * Request adapter of the global request
+ * @param createElementCommand
+ * Create Element Request
+ * @param editingDomain
+ * TransactionalEditingDomain needed to create transactionnal command
+ * @param createElementRequest
+ * The request to create a new element
+ * @param createElementCommand
+ * The command to create the element just after its creation
+ * @return
+ */
+ public static CompositeCommand getSemanticCommand(CreateElementRequestAdapter requestAdapter, TransactionalEditingDomain editingDomain, CreateElementRequest createElementRequest, Command createElementCommand, List<IGraphicalEditPart> graphicalParents) {
+ CompositeCommand semanticCommand;
+ /*
+ * create the semantic create wrapper command
+ */
+ SemanticCreateCommand semanticContainerParentCommand = new SemanticCreateCommand(requestAdapter, createElementCommand);
+ /*
+ * Create a command to update references
+ */
+ SetUpReferencesCommand setUpReferences = new SetUpReferencesCommand(editingDomain, semanticContainerParentCommand.getLabel(), requestAdapter, graphicalParents);
+ /*
+ * create the semantic global command
+ */
+ semanticCommand = new CompositeCommand(semanticContainerParentCommand.getLabel());
+ if(semanticCommand != null) {
+ semanticCommand.compose(semanticContainerParentCommand);
+ }
+ if(setUpReferences != null) {
+ semanticCommand.compose(setUpReferences);
+ }
+ return semanticCommand;
+ }
+
+ /**
+ * Return the command which create the notification to asked to the user to choose the graphical parent of undetermined element (elements which
+ * have at least 2 possible graphical parent)
+ * FIXME change the composite command to a normal command (composite command is not needed anymore)
+ *
+ * @param editingDomain
+ * TransactionalEditingDomain in order to create the command
+ * @param request
+ * General request
+ * @return the composite command. This command is in two parts. The first represent the Notification to choose the model parent and if needed the
+ * command to chose the graphical parent.
+ */
+ public static CompositeCommand getChooseParentNotification(TransactionalEditingDomain editingDomain, CreateViewAndElementRequest request, List<IGraphicalEditPart> graphicalParents, List<IGraphicalEditPart> modelParents, IGraphicalEditPart getHost) {
+ /*
+ * ChooseParentNotificationCommand
+ * 1 - Check if there is any choice to make
+ * 1.1 - Check that All list are initialized
+ * 1.2 - Check there are There at least 2 elements in one of the two least
+ * 2 - Create a composite command :
+ * 2.1 - Create the Graphical Choice command
+ * 2.2 - create the Model Choice command
+ */
+ CompositeCommand choiceCommand = null;
+ if(graphicalParents != null && modelParents != null && (modelParents.size() > 1 || graphicalParents.size() > 1)) {
+ String chooseCommandLabel = "Print choice notifications";//$NON-NLS-1$
+ choiceCommand = new CompositeCommand(chooseCommandLabel);
+ if(modelParents.size() > 1) {
+ ChooseParentNotificationCommand modelNotificationCommand = new ChooseParentNotificationCommand(editingDomain, chooseCommandLabel + " : Model ", modelParents, request, ChooseParentNotificationCommand.MODEL_MODE, getHost);
+ choiceCommand.compose(modelNotificationCommand);
+ } else {
+ if(graphicalParents.size() > 1) {
+ ChooseParentNotificationCommand graphicalNotificationCommand = new ChooseParentNotificationCommand(editingDomain, chooseCommandLabel + " : Graphical ", graphicalParents, request, ChooseParentNotificationCommand.GRAPHICAL_MODE, getHost);
+ choiceCommand.compose(graphicalNotificationCommand);
+ }
+ }
+
+ }
+ return choiceCommand;
+ }
+
+ /**
+ * Return the command which create the notification to asked to the user to choose the graphical parent of undetermined element (elements which
+ * have at least 2 possible graphical parent)
+ * FIXME change the composite command to a normal command (composite command is not needed anymore)
+ *
+ * @param editingDomain
+ * TransactionalEditingDomain in order to create the command
+ * @param childAdapter
+ * {@link IAdaptable} to find the {@link IGraphicalEditPart} of the child
+ * @return the composite command. This command is in two parts. The first represent the Notification to choose the model parent and if needed the
+ * command to chose the graphical parent.
+ */
+ public static CompositeCommand getChooseParentNotification(TransactionalEditingDomain editingDomain, ChangeBoundsRequest request, List<IGraphicalEditPart> graphicalParents, List<IGraphicalEditPart> modelParents, IGraphicalEditPart getHost) {
+ /*
+ * ChooseParentNotificationCommand
+ * 1 - Check if there is any choice to make
+ * 1.1 - Check that All list are initialized
+ * 1.2 - Check there are There at least 2 elements in one of the two least
+ * 2 - Create a composite command :
+ * 2.1 - Create the Graphical Choice command
+ * 2.2 - create the Model Choice command
+ */
+ CompositeCommand choiceCommand = null;
+ if(graphicalParents != null && modelParents != null && (modelParents.size() > 1 || graphicalParents.size() > 1)) {
+ String chooseCommandLabel = "Print choice notifications";//$NON-NLS-1$
+ choiceCommand = new CompositeCommand(chooseCommandLabel);
+ if(modelParents.size() > 1) {
+ ChooseParentNotificationCommand modelNotificationCommand = new ChooseParentNotificationCommand(editingDomain, chooseCommandLabel + " : Model ", modelParents, request, ChooseParentNotificationCommand.MODEL_MODE, getHost);
+ choiceCommand.compose(modelNotificationCommand);
+ } else {
+ if(graphicalParents.size() > 1) {
+ ChooseParentNotificationCommand graphicalNotificationCommand = new ChooseParentNotificationCommand(editingDomain, chooseCommandLabel + " : Graphical ", graphicalParents, request, ChooseParentNotificationCommand.GRAPHICAL_MODE, getHost);
+ choiceCommand.compose(graphicalNotificationCommand);
+ }
+ }
+
+ }
+ return choiceCommand;
+ }
+
+ /**
+ * Check if the child already have a graphical parent and if its graphical parent is not a model parent on the new element in creation
+ *
+ * @param element
+ * Child we want to test
+ * @return true there a other group parent (which is not a parent of the new created element)
+ */
+ public static boolean alreadyHaveGroupGraphicalParent(IGraphicalEditPart element, List<IGraphicalEditPart> modelParents) {
+ IGraphicalEditPart parent = (IGraphicalEditPart)element.getParent();
+ //CHANGE
+ return GroupContainmentRegistry.isContainerConcerned(parent) && !(element.getParent().getChildren().contains(parent));//!modelParents.contains(parent);
+ }
+
+ /**
+ * Get the depth at which the edit part is in the diagram
+ *
+ * @param part
+ * the edit part to test depth
+ * @return number of parents + 1
+ */
+ public static int getDepth(IGraphicalEditPart part) {
+ int depth = 0;
+ EditPart parentPart = part;
+ while(parentPart != null) {
+ parentPart = parentPart.getParent();
+ depth++;
+ }
+ return depth;
+ }
+
+ /**
+ * Select the best models containers among the list of possible parents
+ *
+ * @param parents
+ * group parents
+ * @return the best model container (deepest one) or null if none
+ */
+ public static IGraphicalEditPart selectBestModelContainer(List<IGraphicalEditPart> parents) {
+ IGraphicalEditPart container = null;
+ int containerDepth = 0;
+ //For all elements in parents
+ for(IGraphicalEditPart parent : parents) {
+ // select model containers only
+ if(GroupContainmentRegistry.isContainerModel(parent)) {
+ // select part the deepest in the diagram
+ int depth = getDepth(parent);
+ if(depth > containerDepth) {
+ container = parent;
+ }
+ }
+ }
+ return container;
+ }
+
+ /**
+ * This method is called if no model parent was found. It will return the command handled by a default container.
+ *
+ * @param request
+ * original request
+ * @param createElementRequest
+ * the creation request
+ * @param getHost
+ * Host of the {@link EditPolicy}
+ * @return the command as if handle by the default container. Return if the current container is the default container
+ *
+ */
+ public static Command getCommandFromDefaultModelParent(CreateViewAndElementRequest request, CreateElementRequest createElementRequest, IGraphicalEditPart getHost) {
+ //If no model parent was found
+ //The system will look in the ancestor of the current host to find a element which can contain the new element and which is not a group
+ EClass typeToCreate = createElementRequest.getElementType().getEClass();
+ IGraphicalEditPart hostParent = getHost;
+
+ while(hostParent != null) {
+ EObject hostParentElement = hostParent.resolveSemanticElement();
+ if(GroupContainmentRegistry.getDescriptorsWithContainerEClass(hostParentElement.eClass()).isEmpty()) {
+ for(EReference containmentRelation : hostParentElement.eClass().getEAllContainments()) {
+ if(containmentRelation.getEReferenceType().isSuperTypeOf(typeToCreate)) {
+ if(getHost.equals(hostParent)) {
+ request.getExtendedData().put(NEW_PARENT_HOST, hostParent);
+ createElementRequest.setContainer(hostParentElement);
+ return null;
+ } else {
+ //This edit part can not handle the creation. It send it to the new hostParent
+ request.getExtendedData().put(CommandsUtils.NEW_PARENT_HOST, hostParent);
+ Command cmd = hostParent.getCommand(request);
+ return cmd;
+ }
+ }
+ }
+ }
+ hostParent = (IGraphicalEditPart)hostParent.getParent();
+ }
+ return null;
+ }
+
+ /**
+ * This method is called if no model parent was found. It will return the command handled by a default container. (For change bound request)
+ *
+ * @param request
+ * The change boudn request
+ * @param currentEditPart
+ * The element being moved
+ * @param getHost
+ * The host of the current {@link EditPolicy}
+ * @return the command as if handle by the default container. Return if the current container is the default container
+ */
+ public static Command getCommandFromDefaultModelParent(ChangeBoundsRequest request, IGraphicalEditPart currentEditPart, IGraphicalEditPart getHost) {
+ //If no model parent was found
+ //The system will look in the ancestor of the current host to find a element which can contain the new element and which is not a group
+ EClass typeToCreate = currentEditPart.resolveSemanticElement().eClass();
+ IGraphicalEditPart hostParent = getHost;
+
+ while(hostParent != null) {
+ EObject hostParentElement = hostParent.resolveSemanticElement();
+ if(GroupContainmentRegistry.getDescriptorsWithContainerEClass(hostParentElement.eClass()).isEmpty()) {
+ for(EReference containmentRelation : hostParentElement.eClass().getEAllContainments()) {
+ if(containmentRelation.getEReferenceType().isSuperTypeOf(typeToCreate)) {
+ if(getHost.equals(hostParent)) {
+ return null;
+ } else {
+ //This edit part can not handle the creation. It send it to the new hostParent
+ request.getExtendedData().put(CommandsUtils.NEW_PARENT_HOST, hostParent);
+ Command cmd = hostParent.getCommand(request);
+ return cmd;
+ }
+ }
+ }
+ }
+ hostParent = (IGraphicalEditPart)hostParent.getParent();
+ }
+ return null;
+ }
+
+ /**
+ * Update model for all new direct child.
+ *
+ * @param directChildsToComplete
+ * List of all direct child
+ * @param descriptor
+ * descriptor of the group
+ * @param editingDomain
+ * Editing domain to create command
+ * @param parent
+ * RequestAdapter of the parent creation
+ * @param anyPart
+ * Igraphical editPart to get back EditPartRegistery
+ * @return CompositeCommand of all command updating model for each child
+ */
+ public static ChangeModelParentCommand getUpdateChildrenModel(List<IGraphicalEditPart> directChildsToComplete, AbstractContainerNodeDescriptor descriptor, TransactionalEditingDomain editingDomain, IAdaptable parent, IGraphicalEditPart anyPart) {
+ ChangeModelParentCommand cmd = null;
+ Map<EObject, EReference> elementToMove = new HashMap<EObject, EReference>();
+ if(!directChildsToComplete.isEmpty()) {
+ for(IGraphicalEditPart child : directChildsToComplete) {
+ EObject childEObject = child.resolveSemanticElement();
+ EClass childEClass = childEObject.eClass();
+ if(descriptor.canIBeModelParentOf(childEClass)) {
+ elementToMove.put(childEObject, descriptor.getContainmentReferenceFor(childEClass));
+ }
+ }
+ }
+ if(!elementToMove.isEmpty()) {
+ cmd = new ChangeModelParentCommand(editingDomain, parent, elementToMove, anyPart);
+ }
+ return cmd;
+ }
+
+ /**
+ * set the {@see GroupRequestConstants#GRAPHICAL_CHILDREN} parameter of the request in order to make the list of children available in the
+ * LayoutEditPolicy
+ *
+ * @param automaticChildren
+ * All the {@link IGraphicalEditPart} you want to add as graphical children
+ * @param request
+ * request on which you want to add the parameter
+ */
+ public static void updateGraphicalChildren(List<IGraphicalEditPart> automaticChildren, Request request) {
+ if(!automaticChildren.isEmpty()) {
+ request.getExtendedData().put(GroupRequestConstants.GRAPHICAL_CHILDREN, automaticChildren);
+ }
+ }
+
+ /**
+ * Create a notification to choose the graphical children of element in creation (request)
+ *
+ * @param allChildren
+ * All possible children
+ * @param automaticChildren
+ * All the children has been automatically graphical children
+ * @param request
+ * Creation request
+ * @param domain
+ * EditingDomain to create TransactionalCommand
+ * @param label
+ * Label of the command
+ * @param diagramPart
+ * @return The command or null is not possible
+ */
+ public static CompositeCommand getChooseGraphicalChildrenNotificationCommand(List<IGraphicalEditPart> allChildren, List<IGraphicalEditPart> automaticChildren, CreateViewAndElementRequest request, TransactionalEditingDomain domain, String label, IGraphicalEditPart getHost, DiagramEditPart diagramPart) {
+ if(allChildren.size() > automaticChildren.size()) {
+ Iterator<? extends CreateViewRequest.ViewDescriptor> descriptors = request.getViewDescriptors().iterator();
+ CompositeCommand compositeCommand = new CompositeCommand(label);
+ while(descriptors.hasNext()) {
+ CreateViewRequest.ViewDescriptor descriptor = (CreateViewRequest.ViewDescriptor)descriptors.next();
+ ChooseChildrenNotificationCommand cmd = new ChooseChildrenNotificationCommand(domain, label, allChildren, automaticChildren, descriptor, getHost, diagramPart);
+ if(cmd != null) {
+ compositeCommand.compose(cmd);
+ }
+ }
+ return compositeCommand;
+ }
+ return null;
+ }
+
+ /**
+ * @see #getChooseGraphicalChildrenNotificationCommand(List, List, CreateViewAndElementRequest, TransactionalEditingDomain, String,
+ * IGraphicalEditPart).
+ * This time the we directly give the IAdaptable element of the view
+ * @param allChildren
+ * @see #getChooseGraphicalChildrenNotificationCommand
+ * @param automaticChildren
+ * @see #getChooseGraphicalChildrenNotificationCommand
+ * @param adapter
+ * IAdaptable of the parent group (Used to get the view)
+ * @param domain
+ * @see #getChooseGraphicalChildrenNotificationCommand
+ * @param label
+ * @see #getChooseGraphicalChildrenNotificationCommand
+ * @param getHost
+ * @see #getChooseGraphicalChildrenNotificationCommand
+ * @return
+ */
+ public static CompositeCommand getChooseGraphicalChildrenNotificationCommand(List<IGraphicalEditPart> allChildren, List<IGraphicalEditPart> automaticChildren, IAdaptable adapter, TransactionalEditingDomain domain, String label, IGraphicalEditPart getHost, DiagramEditPart diagramPart) {
+ CompositeCommand result = null;
+ ChooseChildrenNotificationCommand cmd = new ChooseChildrenNotificationCommand(domain, label, allChildren, automaticChildren, adapter, getHost, diagramPart);
+ if(cmd != null) {
+ result = new CompositeCommand(label);
+ result.compose(cmd);
+ }
+ return result;
+ }
+
+ /**
+ * Give back the command to handle visually contained elements inside a new group in creation
+ * 0 - Check if the there is any descriptor (its means if the element in creation belong to the Group Framework
+ * 1 - Compute possible children elements (graphical and model)
+ * 2 - Update References
+ * 3 - Update Model (if needed)
+ * 4 - Reassign automatic graphical parent
+ * 5 - Create a notification command to choose the graphical parent if needed
+ *
+ * @param descriptors
+ * Descriptor of the group in creation
+ * @param request
+ * General request
+ * @param nameObject
+ * Name of the object (to find default size FIXME)
+ * @param diagramPart
+ * EditPart of the diagram
+ * @param editingDomain
+ * TransctionnalEditingDomain in order to create transactionnal command
+ * @param parentAdapter
+ * Parent adapter (Use to get the EObject back after creation and the {@link IGraphicalEditPart})
+ * @param modelParents
+ * @return the composite command of all this steps
+ */
+ public static CompositeCommand getHandleChildrenCommand(Set<AbstractContainerNodeDescriptor> descriptors, Request request, DiagramEditPart diagramPart, TransactionalEditingDomain editingDomain, IAdaptable parentAdapter, List<IGraphicalEditPart> modelParents, IGraphicalEditPart getHost) {
+ CompositeCommand cc = null;
+ //Do the following only if the created element is a group
+ if(!descriptors.isEmpty()) {
+ //Command label
+ String handleChildrenLabel = "Handle Children command ";//$NON-NLS-1$
+ for(AbstractContainerNodeDescriptor descriptor : descriptors) {
+ /*
+ * Child visually contained in the new group which can be graphical children of this new group
+ */
+ List<IGraphicalEditPart> directChildsToComplete = new ArrayList<IGraphicalEditPart>();
+ /*
+ * Old child visually contained before the request ( used in changeBound request )
+ */
+ List<IGraphicalEditPart> oldDirectChildsToComplete = null;
+ /*
+ * Initialize the two list directChildsToComplete and oldDirectChildsToComplete
+ */
+ oldDirectChildsToComplete = initDirectChildLists(request, diagramPart, parentAdapter, descriptor, directChildsToComplete, oldDirectChildsToComplete);
+
+ if((directChildsToComplete != null && !directChildsToComplete.isEmpty()) || (oldDirectChildsToComplete != null && !oldDirectChildsToComplete.isEmpty())) {
+ cc = new CompositeCommand(handleChildrenLabel);
+ /*
+ * List of elements atomically chosen as graphical child
+ */
+ List<IGraphicalEditPart> newGraphicalChildren = new ArrayList<IGraphicalEditPart>();;
+ /*
+ * List of elements on which the user should be asked to choose the graphical parent
+ */
+ List<IGraphicalEditPart> choiceToMakeChildren = new ArrayList<IGraphicalEditPart>();;
+ for(IGraphicalEditPart part : directChildsToComplete) {
+ if(alreadyHaveGroupGraphicalParent(part, modelParents)) {
+ if(isNotAlreadyAGraphicalSon(part, request, parentAdapter)) {
+ choiceToMakeChildren.add(part);
+ }
+ } else {
+ newGraphicalChildren.add(part);
+ }
+ }
+ /*
+ * Command to update model of directChild which can be contain by the moving group
+ */
+ if(!directChildsToComplete.isEmpty()) {
+ ChangeModelParentCommand updateChildrenModel = getUpdateChildrenModel(directChildsToComplete, descriptor, editingDomain, parentAdapter, directChildsToComplete.get(0));
+ if(updateChildrenModel != null) {
+ cc.compose(updateChildrenModel);
+ }
+ }
+ /*
+ * Command to update visually contained element to set their graphical parent with the parent Adapter
+ */
+ if(!newGraphicalChildren.isEmpty()) {
+ updateGraphicalChildren(newGraphicalChildren, request);
+ }
+ String updateCommandeLabel = "Update children references";//$NON-NLS-1$
+ /*
+ * Update all graphical children references and model
+ */
+ updateReferencesAndModelOfGraphicalChildren(request, editingDomain, parentAdapter, cc, directChildsToComplete, oldDirectChildsToComplete, handleChildrenLabel + ":" + updateCommandeLabel + " -> " + "update reference graphical child", getHost, descriptor);
+ /*
+ * Command to update references of new child
+ */
+ UpdateReferencesCommand updateRefCommand = new UpdateReferencesCommand(editingDomain, handleChildrenLabel + ":" + updateCommandeLabel + " -> " + "update reference new child", directChildsToComplete, descriptor, parentAdapter);
+ if(updateRefCommand != null) {
+ cc.compose(updateRefCommand);
+ }
+ /*
+ * Withdraw old referenced child which are not anymore has to be referenced
+ */
+ withdrawOldChildrenReferences(editingDomain, parentAdapter, cc, handleChildrenLabel + ":" + updateCommandeLabel + " -> " + "remove reference from of child", descriptor, directChildsToComplete, oldDirectChildsToComplete);
+
+ /*
+ * Command to create the graphical notification
+ */
+ String chooseGraphicalChildrenLabel = "Notification for choosing graphical children";//$NON-NLS-1$
+ CompositeCommand chooseGraphicalChildrenCommand = null;
+ if(request instanceof CreateViewAndElementRequest) {
+ chooseGraphicalChildrenCommand = getChooseGraphicalChildrenNotificationCommand(directChildsToComplete, newGraphicalChildren, (CreateViewAndElementRequest)request, editingDomain, chooseGraphicalChildrenLabel, getHost, diagramPart);
+ } else if(request instanceof ChangeBoundsRequest) {
+ chooseGraphicalChildrenCommand = getChooseGraphicalChildrenNotificationCommand(directChildsToComplete, newGraphicalChildren, parentAdapter, editingDomain, chooseGraphicalChildrenLabel, getHost, diagramPart);
+ }
+ if(chooseGraphicalChildrenCommand != null) {
+ cc.compose(chooseGraphicalChildrenCommand);
+ }
+
+ cc.reduce();
+ if(cc.isEmpty()) {
+ cc = null;
+ }
+ }
+
+ }
+
+ }
+
+ return cc;
+ }
+
+ /**
+ * True if the request is just a movin request
+ *
+ * @param request
+ * @return
+ */
+ private static boolean isMovingRequest(ChangeBoundsRequest request) {
+ return request.getSizeDelta() == null || request.getSizeDelta().equals(0, 0);
+ }
+
+
+ /***
+ * Update all the graphical children from a model point of view and a reference poitn of view
+ * note: It also update the the lists childlist and oldchildlist. It will withdraw the from those list all graphical children if the reques tis a
+ * simple move. If the request is a resize then all the grazphical children has to be taken into accoutn for next changes
+ *
+ * @param request
+ * {@link ChangeBoundsRequest}
+ * @param editingDomain
+ * {@link TransactionalEditingDomain}
+ * @param parentAdapter
+ * Parent adapter used to get the {@link IGraphicalEditPart} of the parent
+ * @param cc
+ * {@link CompositeCommand} use to compose new commands
+ * @param childList
+ * List of all the visual child after transformation
+ * @param oldChildsList
+ * List of all the visual child before transformation
+ * @param updateCommandeLabel
+ * Label used to compose command
+ * @param getHost
+ * Host of the request
+ */
+ private static void updateReferencesAndModelOfGraphicalChildren(Request request, TransactionalEditingDomain editingDomain, IAdaptable parentAdapter, CompositeCommand cc, List<IGraphicalEditPart> childList, List<IGraphicalEditPart> oldChildsList, String updateCommandeLabel, IGraphicalEditPart getHost, AbstractContainerNodeDescriptor descriptor) {
+ if(request instanceof ChangeBoundsRequest) {
+ Object _movingPart = parentAdapter.getAdapter(EditPart.class);
+ if(_movingPart instanceof IGraphicalEditPart) {
+ List<IGraphicalEditPart> graphicalChilds = new ArrayList<IGraphicalEditPart>();
+ IGraphicalEditPart movingEditPart = (IGraphicalEditPart)_movingPart;
+ //Look for all graphical children
+ graphicalChilds = getGraphicalChild(movingEditPart);
+ /*
+ * For all graphical children
+ * if request = moving request
+ * -> Suppress old references
+ * -> change model parent if needed
+ * -> Add new references
+ * if request = resizing
+ * -> If the resizing is from west side
+ * - Translate the node to unmodify the GMF comportment of resizing by west = node moving
+ * -> If after resizing the node are no longer in the group
+ * - Unset references
+ * - Change graphical parent
+ */
+ ChangeBoundsRequest changeBoundRequest = (ChangeBoundsRequest)request;
+ for(IGraphicalEditPart graphicalChild : graphicalChilds) {
+ /*
+ * All groups that contains the node before transforming ( transforming = moving or resizing )
+ */
+
+ List<IGraphicalEditPart> oldGroupContainer = Utils.createComputeListsOfAllGroupContainerVisually(graphicalChild, changeBoundRequest, false, movingEditPart);
+ /*
+ * All groups that contains the node after transforming
+ */
+ List<IGraphicalEditPart> newGroupContainer = Utils.createComputeListsOfAllGroupContainerVisually(graphicalChild, changeBoundRequest, true, movingEditPart);
+ IGraphicalEditPart compartmentEditPart = (IGraphicalEditPart)Utils.getCompartementEditPartFromMainEditPart(movingEditPart.getViewer().getEditPartRegistry(), movingEditPart);
+ /*
+ * If is a moving request
+ * => Then the node should move with the group
+ */
+ if(isMovingRequest(changeBoundRequest))
+ handleMovingRequestForGraphicalChildren(editingDomain, cc, updateCommandeLabel, getHost, graphicalChild, oldGroupContainer, newGroupContainer, compartmentEditPart);
+ else {
+ cc = handleResizingRequestForGraphicalChildren(editingDomain, parentAdapter, cc, childList, getHost, descriptor, movingEditPart, graphicalChild, changeBoundRequest, newGroupContainer);
+ }
+ }
+ /*
+ * Remove graphical children of the lists of node to handle
+ */
+ childList.removeAll(graphicalChilds);
+ oldChildsList.removeAll(graphicalChilds);
+ }
+ }
+
+ }
+
+ /**
+ * Handle resizing request for all graphical children
+ * - Erase the moving children after resize from WEST/NORT WHEST/WEST
+ * - Handle children going out after resizing
+ *
+ * @param editingDomain
+ * {@link TransactionalEditingDomain}
+ * @param parentAdapter
+ * {@link Adaptable} use to get the {@link IGraphicalEditPart} of the parent at runtime
+ * @param cc
+ * {@link CompositeCommand} Use to add new Command
+ * @param childList
+ * List of all the visual child after transformation
+ * @param getHost
+ * Host of the request
+ * @param descriptor
+ * Descriptor of the group
+ * @param movingEditPart
+ * {@link IGraphicalEditPart} of the moving Edit Part (TODO Use the adapter to erase one argument)
+ * @param graphicalChild
+ * {@link IGraphicalEditPart} of the graphical child you want to handle
+ * @param changeBoundRequest
+ * {@link ChangeBoundsRequest}
+ * @param newGroupContainer
+ * All group which can contain the node after transforming
+ * @return
+ */
+ private static CompositeCommand handleResizingRequestForGraphicalChildren(TransactionalEditingDomain editingDomain, IAdaptable parentAdapter, CompositeCommand cc, List<IGraphicalEditPart> childList, IGraphicalEditPart getHost, AbstractContainerNodeDescriptor descriptor, IGraphicalEditPart movingEditPart, IGraphicalEditPart graphicalChild, ChangeBoundsRequest changeBoundRequest, List<IGraphicalEditPart> newGroupContainer) {
+ /*
+ * If this is a resizing request.
+ * Node should not move => Only case possible = Graphical child which go out from the group
+ * -> Unmove node if resizing from west
+ * -> Handle no coming out
+ */
+
+ int direction = changeBoundRequest.getResizeDirection();
+ Point previousnLocation = graphicalChild.getFigure().getBounds().getLocation().getCopy();
+ Point negatedMoeDelta = changeBoundRequest.getMoveDelta().getNegated().getCopy();
+ boolean correctLocation = false;
+ switch(direction) {
+ case org.eclipse.draw2d.PositionConstants.WEST:
+ previousnLocation.translate(negatedMoeDelta.x, 0);
+ correctLocation = true;
+ break;
+ case org.eclipse.draw2d.PositionConstants.NORTH:
+ previousnLocation.translate(0, negatedMoeDelta.y);
+ correctLocation = true;
+ break;
+ case org.eclipse.draw2d.PositionConstants.NORTH_WEST:
+ previousnLocation.translate(negatedMoeDelta);
+ correctLocation = true;
+ break;
+ default:
+ break;
+ }
+
+ if(!childList.contains(graphicalChild)) {
+ if(correctLocation) {
+ newGroupContainer.remove(movingEditPart);
+ newGroupContainer.remove(Utils.getCompartementEditPartFromMainEditPart(movingEditPart.getViewer().getEditPartRegistry(), movingEditPart));
+ correctLocation = false;
+ }
+ cc = handleGraphicalChildrenMovingOut(editingDomain, parentAdapter, cc, getHost, descriptor, movingEditPart, graphicalChild, newGroupContainer);
+ }
+ if(correctLocation) {
+ SetBoundsCommand sbc = new SetBoundsCommand(editingDomain, "West or North resizing correcting relative coordiante", graphicalChild, previousnLocation);
+ if(sbc != null) {
+ cc.compose(sbc);
+ }
+ }
+ return cc;
+ }
+
+ /**
+ * Handle all the graphical children of a group after a moving request
+ *
+ * @param editingDomain
+ * {@link TransactionalEditingDomain}
+ * @param cc
+ * {@link CommandProxy} to compose new commands
+ * @param updateCommandeLabel
+ * Label Used for the command
+ * @param getHost
+ * Host of the request
+ * @param graphicalChild
+ * Graphical child to handle
+ * @param oldGroupContainer
+ * All group that contained the node before transforming
+ * @param newGroupContainer
+ * All group that contains the node after transforming
+ * @param compartmentEditPart
+ * Compartment EditPart of the parent EditPart
+ */
+ private static void handleMovingRequestForGraphicalChildren(TransactionalEditingDomain editingDomain, CompositeCommand cc, String updateCommandeLabel, IGraphicalEditPart getHost, IGraphicalEditPart graphicalChild, List<IGraphicalEditPart> oldGroupContainer, List<IGraphicalEditPart> newGroupContainer, IGraphicalEditPart compartmentEditPart) {
+ {
+ /*
+ * Suppress old reference
+ */
+ for(IGraphicalEditPart parentGroup : oldGroupContainer) {
+ if(!newGroupContainer.contains(parentGroup) && !parentGroup.equals(compartmentEditPart)) {
+ /*
+ * Unset the reference
+ */
+ UpdateReferencesCommand cmd1 = new UpdateReferencesCommand(editingDomain, updateCommandeLabel, Collections.singletonList(graphicalChild), GroupContainmentRegistry.getContainerDescriptor(parentGroup), parentGroup, UpdateReferencesCommand.UNSET_MODE);
+ if(cmd1 != null) {
+ cc.compose(cmd1);
+ }
+ }
+ }
+ //List of all model parent available (except the compartment edit part)
+ List<IGraphicalEditPart> modelParents = new ArrayList<IGraphicalEditPart>();
+ EObject childEObject = ((IGraphicalEditPart)graphicalChild).resolveSemanticElement();
+ //Does the child have already a valid model parent
+ boolean alreadyHaveValideModelParent = false;
+ AbstractContainerNodeDescriptor containerDescriptor = GroupContainmentRegistry.getContainerDescriptor(compartmentEditPart);
+ //If compartmentEditPart refer to a group which can be model parent then the child already have a model parent
+ if(containerDescriptor != null) {
+ alreadyHaveValideModelParent = containerDescriptor.canIBeModelParentOf(childEObject.eClass());
+ }
+ //Add new reference and update model
+ for(IGraphicalEditPart newParentGroup : newGroupContainer) {
+ //set Reference
+ UpdateReferencesCommand cmd2 = new UpdateReferencesCommand(editingDomain, updateCommandeLabel, Collections.singletonList(graphicalChild), GroupContainmentRegistry.getContainerDescriptor(newParentGroup), newParentGroup, UpdateReferencesCommand.SET_MODE);
+ if(cmd2 != null) {
+ cc.compose(cmd2);
+ }
+ //Create a list of all model parent available. Set alreadyHaveValideModelParent to true if the child already have a model parent wich is on the new model parent
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(newParentGroup);
+ if(desc != null) {
+ if(desc.canIBeModelParentOf(childEObject.eClass())) {
+ modelParents.add(newParentGroup);
+ }
+ }
+ }
+ /*
+ * Do not have mode parent change it
+ */
+ if(!alreadyHaveValideModelParent) {
+ Map<EObject, EReference> child = null;
+ IGraphicalEditPart newModelParent = null;
+ if(!modelParents.isEmpty()) {
+ newModelParent = modelParents.get(0);
+ AbstractContainerNodeDescriptor newDesc = GroupContainmentRegistry.getContainerDescriptor(newModelParent);
+ if(newDesc != null && newModelParent != null) {
+ EReference ref = newDesc.getContainmentReferenceFor(childEObject.eClass());
+ child = Collections.singletonMap(childEObject, ref);
+ }
+ } else {
+ DefaultModelParent parent = Utils.getDefaultModelParent(childEObject.eClass(), getHost);
+ child = Collections.singletonMap(childEObject, parent.geteReference());
+ newModelParent = parent.getiGraphicalEditPart();
+ }
+ if(child != null && newModelParent != null) {
+ ChangeModelParentCommand changeModelParent = new ChangeModelParentCommand(editingDomain, newModelParent, child, newModelParent);
+ if(changeModelParent != null) {
+ cc.compose(changeModelParent);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Handle children movign out from a group after resizing
+ *
+ * @param editingDomain
+ * {@link TransactionalEditingDomain}
+ * @param parentAdapter
+ * Parent adapter to get the {@link IGraphicalEditPart} at runtime
+ * @param cc
+ * {@link CompositeCommand} use to compose new commande
+ * @param getHost
+ * Host of the request
+ * @param descriptor
+ * AbstractContainerNodeDescriptor of the parent
+ * @param movingEditPart
+ * {@link IGraphicalEditPart} of the parent
+ * @param graphicalChild
+ * All graphical children of the group
+ * @param newGroupContainer
+ * Group that containt the node after transforming
+ * @return
+ */
+ private static CompositeCommand handleGraphicalChildrenMovingOut(TransactionalEditingDomain editingDomain, IAdaptable parentAdapter, CompositeCommand cc, IGraphicalEditPart getHost, AbstractContainerNodeDescriptor descriptor, IGraphicalEditPart movingEditPart, IGraphicalEditPart graphicalChild, List<IGraphicalEditPart> newGroupContainer) {
+ String label = Messages.CommandsUtils_HandleGraphicalChildrenMovingOut_Label;
+ if(cc == null) {
+ cc = new CompositeCommand(label);
+ }
+ UpdateReferencesCommand updateRefCommand = new UpdateReferencesCommand(editingDomain, label, Collections.singletonList(graphicalChild), descriptor, parentAdapter, UpdateReferencesCommand.UNSET_MODE);
+ if(updateRefCommand != null) {
+ cc.compose(updateRefCommand);
+ }
+ IGraphicalEditPart newParent = null;
+ if(!newGroupContainer.isEmpty()) {
+ newParent = newGroupContainer.get(0);
+ } else {
+ newParent = (IGraphicalEditPart)movingEditPart.getParent(); //here add a default parent
+ }
+ /*
+ * FIXME
+ * Change
+ * Test is it is a containing feature
+ * Then change containing parent
+ */
+ ChangeGraphicalParentCommand changeParentCmd = new ChangeGraphicalParentCommand(editingDomain, label + ": Changing graphical parent", newParent, graphicalChild, getHost);
+ if(changeParentCmd != null) {
+ cc.compose(changeParentCmd);
+ }
+ return cc;
+ }
+
+
+ /**
+ * Get all {@link IGraphicalEditPart} which are graphical children from a {@link IGraphicalEditPart} parent
+ *
+ * @param parentEditPart
+ * {@link IGraphicalEditPart} parent
+ * @return A {@link List} of {@link IGraphicalEditPart} of all the child and null parent part is not set properly
+ */
+ private static List<IGraphicalEditPart> getGraphicalChild(IGraphicalEditPart parentEditPart) {
+ EditPartViewer viewer = null;
+ List<IGraphicalEditPart> result = null;
+ if(parentEditPart != null) {
+ viewer = parentEditPart.getViewer();
+ if(viewer != null) {
+ IGraphicalEditPart compartmentEditPart = (IGraphicalEditPart)Utils.getCompartementEditPartFromMainEditPart(viewer.getEditPartRegistry(), parentEditPart);
+ result = new ArrayList<IGraphicalEditPart>();
+ for(Object child : compartmentEditPart.getChildren()) {
+ if(child instanceof IGraphicalEditPart && GroupContainmentRegistry.isNodeConcerned((IGraphicalEditPart)child)) {
+ result.add((IGraphicalEditPart)child);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ * Initialize the two list directChildsToComplete and oldDirectChildsToComplete in order to get back all the child visually contained after et
+ * before the request
+ *
+ * @param request
+ * {@link Request} send by the system (for now handle {@link CreateViewAndElementRequest} and {@link ChangeBoundsRequest})
+ * @param diagramPart
+ * EditPart on the diagram
+ * @param parentAdapter
+ * {@link IAdaptable} of the parent group (used to get the {@link IGraphicalEditPart} and {@link View})
+ * @param descriptor
+ * {@link AbstractContainerNodeDescriptor} of the parent group
+ * @param directChildsToComplete
+ * List of all elements which can be graphical child after the request
+ * @param oldDirectChildsToComplete
+ * List of all elements which were graphical child before the request
+ * @return oldDirectChildsToComplete or null if not needed ( in case of {@link CreateViewAndElementRequest})
+ */
+ private static List<IGraphicalEditPart> initDirectChildLists(Request request, IGraphicalEditPart diagramPart, IAdaptable parentAdapter, AbstractContainerNodeDescriptor descriptor, List<IGraphicalEditPart> directChildsToComplete, List<IGraphicalEditPart> oldDirectChildsToComplete) {
+ if(request instanceof CreateViewAndElementRequest) {
+ Utils.createComputedListsOfVisualYRelatedElements(directChildsToComplete, (CreateViewAndElementRequest)request, diagramPart, descriptor);
+ } else if(request instanceof ChangeBoundsRequest) {
+ Object _parentEditPart = parentAdapter.getAdapter(IGraphicalEditPart.class);
+ if(_parentEditPart instanceof IGraphicalEditPart) {
+ oldDirectChildsToComplete = new ArrayList<IGraphicalEditPart>();
+ Utils.createComputedListsOfVisuallyRelatedElements(directChildsToComplete, (ChangeBoundsRequest)request, (IGraphicalEditPart)_parentEditPart, descriptor, true);
+ Utils.createComputedListsOfVisuallyRelatedElements(oldDirectChildsToComplete, (ChangeBoundsRequest)request, (IGraphicalEditPart)_parentEditPart, descriptor, false);
+ }
+ }
+ return oldDirectChildsToComplete;
+ }
+
+ /**
+ * Withdraw all references of element which are no longer contained in the group.
+ * With graphically all the children which are not visually contained in the group
+ *
+ * @param editingDomain
+ * {@link TransactionalEditingDomain}
+ * @param parentAdapter
+ * {@link IAdaptable} of the parent group
+ * @param cc
+ * {@link CompositeCommand} to compose command the new command. (This command will be completed). If cc est nul then a new CompositeCommand
+ * is created
+ * @param handleChildrenLabel
+ * Label for the command
+ * @param descriptor
+ * {@link AbstractContainerNodeDescriptor} of the parent group
+ * @param directChildsToComplete
+ * List of all new element which are visually contained in the parent group
+ * @param oldDirectChildsToComplete
+ * List of all element which were visually contained in the parent group
+ * @return return the composite command or null is no command is in cc
+ */
+ private static CompositeCommand withdrawOldChildrenReferences(TransactionalEditingDomain editingDomain, IAdaptable parentAdapter, CompositeCommand cc, String handleChildrenLabel, AbstractContainerNodeDescriptor descriptor, List<IGraphicalEditPart> directChildsToComplete, List<IGraphicalEditPart> oldDirectChildsToComplete) {
+ if(oldDirectChildsToComplete != null && !oldDirectChildsToComplete.isEmpty()) {
+ List<IGraphicalEditPart> childToWithdraw = new ArrayList<IGraphicalEditPart>();
+ for(IGraphicalEditPart child : oldDirectChildsToComplete) {
+ if(!directChildsToComplete.contains(child)) {
+ childToWithdraw.add(child);
+ }
+ }
+ if(!childToWithdraw.isEmpty()) {
+ String unreferencinComandLabel = "Unset Reference";
+ if(cc == null) {
+ cc = new CompositeCommand(handleChildrenLabel + ":" + unreferencinComandLabel);
+ }
+ UpdateReferencesCommand updateRefCommand = new UpdateReferencesCommand(editingDomain, handleChildrenLabel + ":" + unreferencinComandLabel, childToWithdraw, descriptor, parentAdapter, UpdateReferencesCommand.UNSET_MODE);
+ if(updateRefCommand != null) {
+ cc.compose(updateRefCommand);
+ }
+
+ }
+ cc.reduce();
+ if(cc.isEmpty()) {
+ cc = null;
+ }
+
+ }
+ return cc;
+ }
+
+ private static boolean isNotAlreadyAGraphicalSon(IGraphicalEditPart childPart, Request request, IAdaptable parentAdapter) {
+ if(request instanceof ChangeBoundsRequest) {
+ Object _editPart = parentAdapter.getAdapter(EditPart.class);
+ if(_editPart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart parentPart = (IGraphicalEditPart)_editPart;
+ return !parentPart.getChildren().contains(childPart);
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Set in the reqest the current Graphical parent and the current Model Parent
+ *
+ * @param request
+ * request change want to set
+ * @param _graphicalParents
+ * List of all graphical parent available
+ * @param _modelParents
+ * List of all Model parent available
+ * @param getHost
+ * host of the edit policy
+ * @return Return the default graphical parent
+ */
+ public static IGraphicalEditPart setRequestParentsParameters(Request request, List<IGraphicalEditPart> _graphicalParents, List<IGraphicalEditPart> _modelParents, EditPart getHost) {
+ /*
+ * Choose the default graphical parent
+ * 1 - If no graphical parent found then the host become the graphical parent
+ * else by default the the graphical parent of the list become the graphical parent
+ */
+ IGraphicalEditPart graphicalParent = null;
+ if(!_graphicalParents.isEmpty()) {
+ graphicalParent = _graphicalParents.get(0);
+
+ request.getExtendedData().put(GroupRequestConstants.GRAPHICAL_CONTAINERS, _graphicalParents);
+ }
+ if(_modelParents != null) {
+ request.getExtendedData().put(GroupRequestConstants.MODEL_CONTAINERS, _modelParents);
+ }
+
+
+
+ return graphicalParent;
+ }
+
+ /**
+ * Send the request to a suitable host. A suitable host is a host which can be a model parent of the editing element. This implementation allow
+ * you to deal with creation request
+ *
+ * @param request
+ * CreateViewAndElementRequest of the element in creation
+ * @param createElementRequest
+ * CreateElementRequest of the element in creation
+ * @param getHost
+ * Host of the editPolicy
+ * @param _modelParents
+ * All model parent available
+ * @return
+ */
+ public static Command sendRequestSuitableHost(CreateViewAndElementRequest request, CreateElementRequest createElementRequest, IGraphicalEditPart getHost, List<IGraphicalEditPart> _modelParents) {
+ EObject modelContainer = null;
+ //If the system has found model parent
+ if(!_modelParents.isEmpty()) {
+ IGraphicalEditPart defaultGraphicalEditPart = _modelParents.get(0);
+ //If the current host is different the first element on the modelParent list the system send the request to its edit part
+ if(!getHost.equals(defaultGraphicalEditPart)) {
+ request.getExtendedData().put(NEW_PARENT_HOST, defaultGraphicalEditPart);
+ return defaultGraphicalEditPart.getCommand(request);
+ }
+ modelContainer = getHost.resolveSemanticElement();
+ createElementRequest.setContainer(modelContainer);
+ } else {
+ /*
+ * If there is no model found for this element we use the default element
+ */
+ Command cmd = getCommandFromDefaultModelParent(request, createElementRequest, getHost);
+ if(cmd != null) {
+ return cmd;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Send the request to a suitable host. A suitable host is a host which can be a model parent of the editing element. This implementation allow
+ * you to deal with {@link ChangeBoundsRequest}
+ *
+ * @param request
+ * {@link ChangeBoundsRequest}
+ * @param getHost
+ * {@link EditPart} host of the {@link EditPolicy}
+ * @param _modelParents
+ * List of all {@link IGraphicalEditPart} which can be model parent of the moving element
+ * @param movingEditPart
+ * The {@link IGraphicalEditPart} of the moving {@link EditPart}
+ * @return
+ */
+ public static Command sendRequestSuitableHost(ChangeBoundsRequest request, IGraphicalEditPart getHost, List<IGraphicalEditPart> _modelParents, IGraphicalEditPart movingEditPart) {
+ //If the system has found model parent
+ if(!_modelParents.isEmpty()) {
+ IGraphicalEditPart defaultModelParentEditPart;
+ //TODO redo tests with this
+ if(_modelParents.contains(movingEditPart.getParent())) {
+ defaultModelParentEditPart = (IGraphicalEditPart)movingEditPart.getParent();
+ } else {
+ defaultModelParentEditPart = _modelParents.get(0);
+ }
+ //If the current host is different the first element on the modelParent list the system send the request to its edit part
+ if(!getHost.equals(defaultModelParentEditPart)) {
+ return defaultModelParentEditPart.getCommand(request);
+ }
+
+ } else {
+ /*
+ * If there is no model found for this element we use the default element
+ * FIXME 1 - Check the safety of editParts.get(0) . Try to move several element in the same time
+ */
+
+ Command cmd = getCommandFromDefaultModelParent(request, movingEditPart, getHost);
+ if(cmd != null) {
+ return cmd;
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * This method handle request with multiple EditPart ( @see {@link ChangeBoundsRequest#getEditParts()} ).
+ * It will handle it by creating as many request as {@link EditPart} in {@link ChangeBoundsRequest#getEditParts()} and ask the host to handle it.
+ *
+ * @param request
+ * {@link ChangeBoundsRequest}
+ * @param label
+ * label of the resulting command if any
+ * @param getHost
+ * Host of the editPolicy
+ * @return Return the composite command if any. Null it the request has less than 2 edit part
+ */
+ public static Command requestEditPartMultiplexor(ChangeBoundsRequest request, String label, IGraphicalEditPart getHost) {
+ CompositeCommand result = new CompositeCommand(label);
+ if(request.getEditParts().size() > 1) {
+ for(Object part : request.getEditParts()) {
+ ChangeBoundsRequest req = new ChangeBoundsRequest();
+ req.setEditParts(Collections.singletonList(part));
+ req.setMoveDelta(request.getMoveDelta());
+ req.setSizeDelta(request.getSizeDelta());
+ req.setLocation(request.getLocation());
+ req.setResizeDirection(request.getResizeDirection());
+ req.setCenteredResize(request.isCenteredResize());
+ req.setConstrainedMove(request.isConstrainedMove());
+ req.setConstrainedResize(request.isConstrainedResize());
+ req.setSnapToEnabled(request.isSnapToEnabled());
+ req.setType(RequestConstants.REQ_RESIZE_CHILDREN);
+ HashMap extendedData = new HashMap(request.getExtendedData());
+ req.setExtendedData(extendedData);
+ // Command cmd = getHost.getCommand(req);
+ Command cmd = getHost.getEditPolicy(EditPolicy.LAYOUT_ROLE).getCommand(req);
+ if(cmd != null) {
+ result.compose(new CommandProxy(cmd));
+ }
+ }
+ if(!result.isEmpty()) {
+ return new ICommandProxy(result);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Compose the command to change the graphical parent
+ *
+ * @param label
+ * Label of the command
+ * @param result
+ * Resulting composite command
+ * @param movingEditPart
+ * The {@link IGraphicalEditPart} which is moving
+ * @param editingDomain
+ * {@link TransactionalEditingDomain} use to create Transactionnal Command
+ * @param graphicalParent
+ * The new graphical parent
+ * @param request
+ */
+ public static void getChangeGraphicalParentCommand(String label, CompositeCommand result, IGraphicalEditPart movingEditPart, TransactionalEditingDomain editingDomain, IGraphicalEditPart graphicalParent, IGraphicalEditPart getHost, ChangeBoundsRequest request) {
+ if(graphicalParent != null) {
+ ChangeGraphicalParentCommand changeGraphicalParent = new ChangeGraphicalParentCommand(editingDomain, label + ": change graphical parent", graphicalParent, movingEditPart, (IGraphicalEditPart)getHost, request);
+ if(changeGraphicalParent != null) {
+ changeGraphicalParent.setMode(Mode.MOVE_CHILD);
+ result.compose(changeGraphicalParent);
+ }
+ } else {
+ ChangeGraphicalParentCommand changeGraphicalParent = new ChangeGraphicalParentCommand(editingDomain, label + ": change graphical parent", (IGraphicalEditPart)getHost, movingEditPart, (IGraphicalEditPart)getHost, request);
+ if(changeGraphicalParent != null) {
+ changeGraphicalParent.setMode(Mode.MOVE_CHILD);
+ result.compose(changeGraphicalParent);
+ }
+ }
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/GroupNotificationBuilderFactory.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/GroupNotificationBuilderFactory.java
new file mode 100644
index 00000000000..33f9394e8db
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/GroupNotificationBuilderFactory.java
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.CompositeCreatorWithCommand;
+import org.eclipse.papyrus.ui.toolbox.notification.Type;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.NotificationBuilder;
+
+/**
+ * This class builds all the necessary notifications for the group framework.
+ * It allows to recover configured, ready to run, notification builders.
+ *
+ * @author vhemery
+ */
+public class GroupNotificationBuilderFactory {
+
+ /**
+ * This class allow to recover a NotificationBuilder and a command defined by the notification execution.
+ */
+ public static class NotificationBuilderAndResultingCommand {
+
+ private NotificationBuilder builder;
+
+ private CompositeCreatorWithCommand creator;
+
+ public NotificationBuilderAndResultingCommand(NotificationBuilder notificationBuilder, CompositeCreatorWithCommand creatorWithCommand) {
+ builder = notificationBuilder;
+ creator = creatorWithCommand;
+ }
+
+ public NotificationBuilder getBuilder() {
+ return builder;
+ }
+
+ public Command getResultingCommand() {
+ return creator.getResultingCommand();
+ }
+
+ public CompositeCreatorWithCommand getCreator() {
+ return creator;
+ }
+ }
+
+ /**
+ * Create a simple notification builder from a label
+ *
+ * @param label
+ * Title of your notification
+ * @return a NotificationBuilder
+ */
+ public static NotificationBuilder getQuestionBuilder(String label) {
+ NotificationBuilder builder = NotificationBuilder.createInformationBuilder();
+ builder.setType(Type.QUESTION);
+ builder.setTemporary(true);
+ builder.setAsynchronous(true);
+ builder.setTitle(label);
+ return builder;
+
+ }
+
+ /**
+ * Create a simple warning notification builder from a label
+ *
+ * @param label
+ * Title of your notification
+ * @return a NotificationBuilder
+ */
+ public static NotificationBuilder getWarningBuilder(String label) {
+ NotificationBuilder builder = NotificationBuilder.createInformationBuilder();
+ builder.setType(Type.WARNING);
+ builder.setTemporary(true);
+ builder.setAsynchronous(true);
+ builder.setTitle(label);
+ return builder;
+
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/PendingGroupNotificationsManager.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/PendingGroupNotificationsManager.java
new file mode 100644
index 00000000000..9cdd59df424
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/PendingGroupNotificationsManager.java
@@ -0,0 +1,181 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.ChooseChildrenNotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.ChooseParentNotificationConfigurator;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.NotificationConfigurator;
+import org.eclipse.papyrus.ui.toolbox.notification.INotification;
+
+/**
+ * The pending group notifications manager handles notifications which have not been resolved.
+ * It ensures that notifications are reconducted in the next notification and that old notifications are deleted.
+ *
+ * @author vhemery
+ */
+public class PendingGroupNotificationsManager {
+
+ /** the instances */
+ private static Map<DiagramEditPart, PendingGroupNotificationsManager> instances = new HashMap<DiagramEditPart, PendingGroupNotificationsManager>();
+
+ private DiagramEditPart diagramEditPart = null;
+
+ private Map<IGraphicalEditPart, NotificationConfigurator> chooseParentNotifications = new HashMap<IGraphicalEditPart, NotificationConfigurator>();
+
+ private HashMap<IGraphicalEditPart, NotificationConfigurator> chooseChildrenNotifications = new HashMap<IGraphicalEditPart, NotificationConfigurator>();
+
+ private PendingGroupNotificationsManager(DiagramEditPart diagramPart) {
+ diagramEditPart = diagramPart;
+ }
+
+ /**
+ * Delete this manager and its external references.
+ */
+ public void delete() {
+ chooseParentNotifications.clear();
+ chooseChildrenNotifications.clear();
+ instances.remove(diagramEditPart);
+ diagramEditPart = null;
+
+ }
+
+ /**
+ * Access to an existing instance or create a new one for an active diagram
+ *
+ * @param diagramPart
+ * the active diagram part
+ * @return the PendingGroupNotificationsManager instance for the active diagram or null if the diagram is unactive
+ */
+ public static PendingGroupNotificationsManager getInstanceForDiagram(DiagramEditPart diagramPart) {
+ if(diagramPart.isActive()) {
+ if(!instances.containsKey(diagramPart)) {
+ PendingGroupNotificationsManager instance = new PendingGroupNotificationsManager(diagramPart);
+ instances.put(diagramPart, instance);
+ return instance;
+ } else {
+ return instances.get(diagramPart);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Delete the PendingGroupNotificationsManager instance corresponding to this diagram part
+ *
+ * @param diagramPart
+ * the diagram edit part
+ */
+ public static void removeInstanceForDiagram(DiagramEditPart diagramPart) {
+ if(instances.containsKey(diagramPart)) {
+ instances.get(diagramPart).delete();
+ }
+ }
+
+ /**
+ * Update the map and delete the no longer needed notifications.
+ * The old notification entries are added to the map, unneccessary entries are removed.
+ *
+ * @param movedPartsAndParents
+ * the map with moved parts and their parent groups
+ */
+ // public void updateParentAssignementsMap(Map<IGraphicalEditPart, List<IGraphicalEditPart>> movedPartsAndParents) {
+ // Set<IGraphicalEditPart> newlyMovedParts = movedPartsAndParents.keySet();
+ // if(newlyMovedParts.size() > 0) {
+ // // the parent assignment from the same diagram must be combined
+ // // 1. report unchanged assignments in the new map
+ // Map<INotification, ChooseContainingGroupCreator> copy = new HashMap<INotification, ChooseContainingGroupCreator>(chooseParentNotifications);
+ // for(Entry<INotification, ChooseContainingGroupCreator> creatorEntry : copy.entrySet()) {
+ // if(!creatorEntry.getKey().isDeleted()) {
+ // // report
+ // ChooseContainingGroupCreator creator = creatorEntry.getValue();
+ // Map<IGraphicalEditPart, List<IGraphicalEditPart>> previousAssignement = creator.getElementsAndParents();
+ // Set<IGraphicalEditPart> oldlyMovedParts = new HashSet<IGraphicalEditPart>(previousAssignement.keySet());
+ // oldlyMovedParts.removeAll(newlyMovedParts);
+ // for(IGraphicalEditPart partToReport : oldlyMovedParts) {
+ // // do not report orphan parts
+ // if(partToReport.getParent() != null) {
+ // movedPartsAndParents.put(partToReport, previousAssignement.get(partToReport));
+ // }
+ // }
+ // } else {
+ // // remove deleted notification from manager
+ // chooseParentNotifications.remove(creatorEntry.getKey());
+ // }
+ // }
+ // // 2. delete old notification
+ // removeChooseParentNotification();
+ // }
+ // // clean useless assignments with only one parent
+ // for(Entry<IGraphicalEditPart, List<IGraphicalEditPart>> entry : new HashMap<IGraphicalEditPart, List<IGraphicalEditPart>>(movedPartsAndParents).entrySet()) {
+ // if(entry.getValue().size() < 2) {
+ // movedPartsAndParents.remove(entry.getKey());
+ // }
+ // }
+ // }
+
+ /**
+ * Remove notifications to assign the graphical parent group
+ */
+ public void removeChooseParentNotification(IGraphicalEditPart childEditPart) {
+ chooseParentNotifications.remove(childEditPart);
+ }
+
+ /**
+ * Remove notification to assign a group's graphical children
+ *
+ * @param parentGroup
+ * the group
+ */
+ public void removeChooseChildrenNotification(IGraphicalEditPart parentGroup) {
+ chooseChildrenNotifications.remove(parentGroup);
+ }
+
+
+
+ /**
+ * Store a notification and its composite creator to let it be managed
+ *
+ * @param creator
+ * the composite creator
+ * @param notification
+ * the notification
+ */
+ public void storeNotification(NotificationConfigurator configurator) {
+ if(configurator instanceof ChooseParentNotificationConfigurator) {
+ chooseParentNotifications.put(((ChooseParentNotificationConfigurator)configurator).getMainEditPart(), configurator);
+ } else if(configurator instanceof ChooseChildrenNotificationConfigurator) {
+ chooseChildrenNotifications.put(((ChooseChildrenNotificationConfigurator)configurator).getMainEditPart(), configurator);
+ }
+ }
+
+ /**
+ * Get the {@link INotification} for choosing the children of an edit and return null is there none
+ *
+ * @param parentEditPart
+ * @return
+ */
+ public NotificationConfigurator getChooseChildrenPendingNotification(IGraphicalEditPart parentEditPart) {
+ if(chooseChildrenNotifications.containsKey(parentEditPart)) {
+ return chooseChildrenNotifications.get(parentEditPart);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/groupcontainment/GroupContainmentRegistry.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/groupcontainment/GroupContainmentRegistry.java
new file mode 100644
index 00000000000..b9caf4e3bd5
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/groupcontainment/GroupContainmentRegistry.java
@@ -0,0 +1,268 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.groupcontainment;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+
+
+/**
+ * This registry recovers information from the extensions for the GroupContainment point.
+ *
+ * @author vhemery
+ */
+public class GroupContainmentRegistry {
+
+ /** The GroupContainment extension point id */
+ private static final String GROUP_EXTENSION_POINT = "org.eclipse.papyrus.diagram.common.groups.groupcontainment";
+
+ /** The name of the extension node for model containment */
+ private static final String MODEL_CONTAINER_NODE = "modelContainer";
+
+ /** The name of the extension node for graphical container with model reference */
+ private static final String REFERENCE_CONTAINER_NODE = "referenceContainer";
+
+ /** The name of the descriptor attribute */
+ private static final String CONTAINER_DESCRIPTOR_ATTRIBUTE = "descriptor";
+
+ /** The name of the edit part type attribute */
+ private static final String EDIT_PART_TYPE_ATTRIBUTE = "editPartType";
+
+ /** The map of descriptors for model containers, by type of edit part */
+ private static Map<String, AbstractContainerNodeDescriptor> modelContainersDescriptors = new HashMap<String, AbstractContainerNodeDescriptor>();
+
+ /** The map of descriptors for graphical containers only, by type of edit part */
+ private static Map<String, AbstractContainerNodeDescriptor> graphicalContainersDescriptors = new HashMap<String, AbstractContainerNodeDescriptor>();
+
+ /** The map of descriptor allowing to recover the group part from a view, by view type */
+ private static Map<String, AbstractContainerNodeDescriptor> descriptorForViewType = new HashMap<String, AbstractContainerNodeDescriptor>();
+
+
+ /**
+ * Initialize the values from the extension point
+ */
+ static {
+ initialize();
+ }
+
+ /**
+ * Load all extensions and register the container descriptors
+ */
+ public static void initialize() {
+ // Load extensions of edit part mapping
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extensionPoint = registry.getExtensionPoint(GROUP_EXTENSION_POINT);
+ for(IExtension extension : extensionPoint.getExtensions()) {
+ for(IConfigurationElement providing : extension.getConfigurationElements()) {
+ if(MODEL_CONTAINER_NODE.equals(providing.getName())) {
+ String editPartType = providing.getAttribute(EDIT_PART_TYPE_ATTRIBUTE);
+ if(editPartType != null) {
+ try {
+ Object provider = providing.createExecutableExtension(CONTAINER_DESCRIPTOR_ATTRIBUTE);
+ if(provider instanceof AbstractContainerNodeDescriptor) {
+ modelContainersDescriptors.put(editPartType, (AbstractContainerNodeDescriptor)provider);
+ }
+ } catch (CoreException e) {
+ // ignore this extension node
+ }
+ }
+ } else if(REFERENCE_CONTAINER_NODE.equals(providing.getName())) {
+ String editPartType = providing.getAttribute(EDIT_PART_TYPE_ATTRIBUTE);
+ if(editPartType != null) {
+ try {
+ Object provider = providing.createExecutableExtension(CONTAINER_DESCRIPTOR_ATTRIBUTE);
+ if(provider instanceof AbstractContainerNodeDescriptor) {
+ graphicalContainersDescriptors.put(editPartType, (AbstractContainerNodeDescriptor)provider);
+ }
+ } catch (CoreException e) {
+ // ignore this extension node
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Get the AbstractContainerNodeDescriptor from a EClass
+ *
+ * @param containerEClass
+ * @return Set<AbstractContainerNodeDescriptor> Return all the descriptor which match the corresponding EClass
+ */
+ public static Set<AbstractContainerNodeDescriptor> getDescriptorsWithContainerEClass(EClass containerEClass) {
+ Set<AbstractContainerNodeDescriptor> descriptors = new HashSet<AbstractContainerNodeDescriptor>(modelContainersDescriptors.size() + graphicalContainersDescriptors.size());
+ Set<AbstractContainerNodeDescriptor> descriptorsResult = new HashSet<AbstractContainerNodeDescriptor>(modelContainersDescriptors.size() + graphicalContainersDescriptors.size());
+ descriptors.addAll(modelContainersDescriptors.values());
+ descriptors.addAll(graphicalContainersDescriptors.values());
+ // filter descriptors
+ for(AbstractContainerNodeDescriptor descriptor : descriptors) {
+ if(descriptor.getContainerEClass().equals(containerEClass)) {
+ descriptorsResult.add(descriptor);
+ }
+ }
+ return descriptorsResult;
+ }
+
+ /**
+ * Get all the references which can point to a group
+ *
+ * @return give back a set of ERefences pointing at group
+ */
+ public static Set<EReference> getAllERefencesFromNodeToGroup() {
+ Set<EReference> referencesResult = new HashSet<EReference>();
+ Set<AbstractContainerNodeDescriptor> descriptors = new HashSet<AbstractContainerNodeDescriptor>(modelContainersDescriptors.size() + graphicalContainersDescriptors.size());
+ descriptors.addAll(modelContainersDescriptors.values());
+ descriptors.addAll(graphicalContainersDescriptors.values());
+ for(AbstractContainerNodeDescriptor descriptor : descriptors) {
+ for(EReference ref : descriptor.getChildrenReferences()) {
+ EReference eoppositeRef = ref.getEOpposite();
+ if(eoppositeRef != null) {
+ referencesResult.add(eoppositeRef);
+ }
+ }
+
+ }
+ return referencesResult;
+ }
+
+ /**
+ * Know whether the edit part is concerned by the group framework, which means there is a container descriptor for its class.
+ *
+ * @param editPart
+ * the edit part to test
+ * @return true if there is a descriptor
+ */
+ public static boolean isContainerConcerned(IGraphicalEditPart editPart) {
+ if(editPart == null) {
+ return false;
+ }
+ String editPartClassName = editPart.getClass().getCanonicalName();
+ return modelContainersDescriptors.containsKey(editPartClassName) || graphicalContainersDescriptors.containsKey(editPartClassName);
+ }
+
+ /**
+ * Return true it the element pointed by the EditPart is a node whicj=h is concerned by the framework
+ *
+ * @param editPart
+ * of EObject you want to test
+ * @return
+ */
+ public static boolean isNodeConcerned(IGraphicalEditPart editPart) {
+ EClass current = editPart.resolveSemanticElement().eClass();
+ Set<EReference> allReferences = new HashSet<EReference>();
+ for(AbstractContainerNodeDescriptor nodeDesc1 : modelContainersDescriptors.values()) {
+ allReferences.addAll(nodeDesc1.getChildrenReferences());
+ }
+ for(AbstractContainerNodeDescriptor nodeDesc2 : graphicalContainersDescriptors.values()) {
+ allReferences.addAll(nodeDesc2.getChildrenReferences());
+ }
+ for(EReference ref : allReferences) {
+ if(ref.getEReferenceType().isSuperTypeOf(current)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get the group descriptor of the edit part concerned by the group framework.
+ * Warning the edit part has to be exactly the same than the one register in the extension point.
+ * For example in the case of Activity Diagram. Onlu the compartment edit Part are register.
+ *
+ * @param editPart
+ * the edit part to get descriptor of
+ * @return container node descriptor or null if none
+ */
+ public static AbstractContainerNodeDescriptor getContainerDescriptor(IGraphicalEditPart editPart) {
+ String editPartClassName = editPart.getClass().getCanonicalName();
+ if(modelContainersDescriptors.containsKey(editPartClassName)) {
+ return modelContainersDescriptors.get(editPartClassName);
+ } else if(graphicalContainersDescriptors.containsKey(editPartClassName)) {
+ return graphicalContainersDescriptors.get(editPartClassName);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Know whether the edit part concerned by the group framework is a model container.
+ *
+ * @param editPart
+ * the edit part to test
+ * @return true if the container is a direct model container
+ */
+ public static boolean isContainerModel(IGraphicalEditPart editPart) {
+ String editPartClassName = editPart.getClass().getCanonicalName();
+ return modelContainersDescriptors.containsKey(editPartClassName);
+ }
+
+ /**
+ * Get the group compartment part (containing children elements) from a view of the node
+ *
+ * @param view
+ * a view, either of the compartment, or the primary node view
+ * @param diagramPart
+ * the diagram edit part to recover parts from views
+ * @return the group compartment part or null if none is adequate for the group framework
+ */
+ public static IGraphicalEditPart getGroupContainingPartFromView(View view, DiagramEditPart diagramPart) {
+ String viewType = view.getType();
+ if(descriptorForViewType.containsKey(viewType)) {
+ // the appropriate descriptor has already been found for this view type
+ AbstractContainerNodeDescriptor desc = descriptorForViewType.get(viewType);
+ if(desc != null) {
+ return desc.getPartFromView(view, diagramPart);
+ } else {
+ return null;
+ }
+ } else {
+ // find the the appropriate descriptor for this view type
+ for(AbstractContainerNodeDescriptor desc : modelContainersDescriptors.values()) {
+ IGraphicalEditPart res = desc.getPartFromView(view, diagramPart);
+ if(res != null) {
+ // register for further use
+ descriptorForViewType.put(viewType, desc);
+ return res;
+ }
+ }
+ for(AbstractContainerNodeDescriptor desc : graphicalContainersDescriptors.values()) {
+ IGraphicalEditPart res = desc.getPartFromView(view, diagramPart);
+ if(res != null) {
+ // register for further use
+ descriptorForViewType.put(viewType, desc);
+ return res;
+ }
+ }
+ // register no result for further use
+ descriptorForViewType.put(viewType, null);
+ return null;
+ }
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CheckboxIGraphicalFocusListenner.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CheckboxIGraphicalFocusListenner.java
new file mode 100644
index 00000000000..91f87e441c8
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CheckboxIGraphicalFocusListenner.java
@@ -0,0 +1,52 @@
+package org.eclipse.papyrus.diagram.common.groups.core.ui;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.graphics.RGB;
+
+
+public class CheckboxIGraphicalFocusListenner implements MouseTrackListener {
+
+
+ private int oldColor, newColor;
+
+ private View parentView;
+
+ private TransactionalEditingDomain editingDomain;
+
+
+ public CheckboxIGraphicalFocusListenner(IGraphicalEditPart parent) {
+ super();
+ this.parentView = (View)parent.getModel();
+ newColor = FigureUtilities.RGBToInteger(new RGB(255, 0, 0));
+
+ }
+
+
+ public void mouseEnter(MouseEvent arg0) {
+
+ // SetPropertyCommand changeColor = new SetPropertyCommand( editingDomain,"blabla",parentView,NotationPackage.Literals.LINE_STYLE,newColor);
+ }
+
+ public void mouseExit(MouseEvent arg0) {
+ // LineStyle lineStyle = (LineStyle)parentView.getStyle(NotationPackage.Literals.LINE_STYLE);
+ // if(lineStyle != null) {
+ // // line color
+ // //RGB lineRGB = PreferenceConverter.getColor(store, preferenceLineColorName);
+ // newColor = lineStyle.getLineColor();
+ // lineStyle.setLineColor(oldColor);
+ // }
+
+
+ }
+
+ public void mouseHover(MouseEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseChildrenNotificationConfigurator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseChildrenNotificationConfigurator.java
new file mode 100644
index 00000000000..78ff2e44dca
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseChildrenNotificationConfigurator.java
@@ -0,0 +1,293 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.diagram.common.groups.Messages;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.utils.CreatorUtils;
+import org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.IContext;
+import org.eclipse.swt.SWT;
+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.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * Create a IComposite creator to ask the user to choose the graphical parent of a list of possible children
+ * and then run the command to change the graphical parent
+ *
+ * @author arthur daussy
+ *
+ */
+public class ChooseChildrenNotificationConfigurator extends NotificationConfigurator {
+
+ /**
+ * EditPart of the parent
+ */
+ private IGraphicalEditPart parentEditPart;
+
+ /**
+ * All possible graphical children
+ */
+ protected List<IGraphicalEditPart> allChildren;
+
+ /**
+ * All children which are automatically chosen as graphical child
+ */
+ protected List<IGraphicalEditPart> automaticChildren;
+
+ /**
+ * buttons for children
+ */
+ private Map<Button, IGraphicalEditPart> childCheckBoxes;
+
+ /**
+ * {@link EditPart} hosting the {@link EditPolicy}
+ */
+ protected IGraphicalEditPart host;
+
+
+ /**
+ * Construct a {@link ICompositeCreator} in order to asked the user to choose children among a given list
+ * Constructor.
+ *
+ * @param parentEditPart
+ * EditPart of the parent (This part can be the {@link CompartmentEditPart} or the main {@link EditPart} of the element
+ * @param allChildren
+ * @see {@link #allChildren}
+ * @param automaticChildren
+ * @see {@link #automaticChildren}
+ */
+ public ChooseChildrenNotificationConfigurator(IGraphicalEditPart parentEditPart, List<IGraphicalEditPart> allChildren, List<IGraphicalEditPart> automaticChildren, IGraphicalEditPart host, PendingGroupNotificationsManager manager) {
+ super(parentEditPart, manager, Messages.ChooseChildrenICompositeCreator_ChooseChildren, Mode.QUESTION_MODE);
+ this.parentEditPart = parentEditPart;
+ this.allChildren = allChildren;
+ this.automaticChildren = automaticChildren;
+ this.host = host;
+ this.childCheckBoxes = new HashMap<Button, IGraphicalEditPart>();
+ }
+
+ /**
+ * Run the notification and create a changeGrazphicalParent for each selected element
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#run(org.eclipse.papyrus.ui.toolbox.notification.builders.IContext)
+ * @param context
+ */
+ public void run(IContext context) {
+ TransactionalEditingDomain editingDomain = mainEditPart.getEditingDomain();
+ Set<IGraphicalEditPart> childrenUpdated = new HashSet<IGraphicalEditPart>();
+ for(Button checkBoxButton : childCheckBoxes.keySet()) {
+ if(checkBoxButton.getSelection() && checkBoxButton.isEnabled()) {
+ IGraphicalEditPart childPart = childCheckBoxes.get(checkBoxButton);
+ if(!childrenUpdated.contains(childPart)) {
+ changeGraphicalParentOf(editingDomain, childPart);
+ childrenUpdated.add(childPart);
+ }
+ }
+ }
+ closeNotitfication(context);
+ }
+
+ /**
+ * @param editingDomain
+ * @param childPart
+ */
+ private void changeGraphicalParentOf(TransactionalEditingDomain editingDomain, IGraphicalEditPart childPart) {
+ String label = "Change graphical parent" + " of " + CreatorUtils.getLabel(childPart) + " to " + CreatorUtils.getLabel(mainEditPart);
+ ChangeGraphicalParentCommand cmd = new ChangeGraphicalParentCommand(editingDomain, label, mainEditPart, childPart, host);
+ if(cmd != null && cmd.canExecute()) {
+ //Execute the command
+ editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(cmd));
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator#createComposite(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ *
+ * @param parent
+ * @param toolkit
+ * @return
+ */
+ public Composite createComposite(Composite parent, FormToolkit toolkit) {
+ if(toolkit == null) {
+ toolkit = new FormToolkit(parent.getDisplay());
+ }
+ Composite top = toolkit.createComposite(parent, SWT.NONE);
+ top.setLayout(new FormLayout());
+ FormText textLabel = toolkit.createFormText(top, false);
+ textLabel.setText(Messages.ChooseParentNotificationCommand_ChooseGraphicalChildrenMessage + CreatorUtils.getLabel(mainEditPart) + " :", false, true);
+ FormData data = new FormData();
+ textLabel.setLayoutData(data);
+ Control previousElement = textLabel;
+ /*
+ * Create for each parents a checkbox
+ */
+ createCheckBoxes(toolkit, top, previousElement);
+
+
+ return top;
+ }
+
+ /**
+ * Create all the check boxes needed.
+ * If child is automatically assign to this parent then it appeares but it is disable
+ * If a child has already a parent:
+ * If its parent is the current EditPart then it is selected
+ * If not then it is not selected
+ *
+ * @param toolkit
+ * @see {@link ICompositeCreator}
+ * @param top
+ * @see {@link ICompositeCreator}
+ * @param previousElement
+ * A control element under which the check boxes bill be displayed
+ */
+ private void createCheckBoxes(FormToolkit toolkit, Composite top, Control previousElement) {
+ FormData data;
+ for(final IGraphicalEditPart child : allChildren) {
+ String label = CreatorUtils.getLabel(child);
+ Button checkBox = toolkit.createButton(top, label, SWT.CHECK);
+ //FIXME finish the MouseTrackLMistenner
+ // checkBox.addMouseTrackListener(new CheckboxIGraphicalFocusListenner(child));
+ //If the child has already parentEditPart as graphical parent the notification will not display it
+ if(!child.getParent().equals(mainEditPart)) {
+ if(automaticChildren.contains(child)) {
+ checkBox.setSelection(true);
+ checkBox.setEnabled(false);
+
+ } else {
+ checkBox.setSelection(false);
+ }
+ data = CreatorUtils.getFormDataUnder(previousElement);
+ checkBox.setLayoutData(data);
+ previousElement = checkBox;
+ childCheckBoxes.put(checkBox, child);
+ }
+ // add dispose listener to remove from handled widgets
+ checkBox.addDisposeListener(new DisposeListener() {
+
+ /**
+ * Remove widget from handled ones
+ *
+ * @param e
+ * the dispose event
+ */
+ public void widgetDisposed(DisposeEvent e) {
+ childCheckBoxes.remove(e.widget);
+ }
+ });
+
+ checkBox.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Widget check = e.widget;
+ if(check instanceof Button) {
+ boolean selection = ((Button)check).getSelection();
+ for(Button b : getAllButtonFor(child)) {
+ b.setSelection(selection);
+ }
+ }
+ }
+
+ /**
+ * This method will return a list of all button referencing a {@link IGraphicalEditPart}
+ *
+ * @param child
+ * The {@link IGraphicalEditPart} of which you want to find the {@link Button}
+ * @return List of all button
+ */
+ private List<Button> getAllButtonFor(IGraphicalEditPart child) {
+ List<Button> result = new ArrayList<Button>();
+ for(Button childButton : childCheckBoxes.keySet()) {
+ IGraphicalEditPart childEdipart = childCheckBoxes.get(childButton);
+ if(childEdipart.equals(child)) {
+ result.add(childButton);
+ }
+ }
+ return result;
+ }
+ });
+ }
+ }
+
+
+ /**
+ * This method check if the {@link ChooseChildrenNotificationConfigurator} create with all the following parameters would be different from the
+ * current one
+ *
+ * @param _parentEditPart
+ * @see {@link #mainEditPart}
+ * @param _allChildren
+ * @see {@link #allChildren}
+ * @param _automaticChildren
+ * @see {@link #automaticChildren}
+ * @param _host
+ * @see {@link #host}
+ * @return true the notification would be different
+ */
+ public boolean isThereAnyModification(IGraphicalEditPart _parentEditPart, List<IGraphicalEditPart> _allChildren, List<IGraphicalEditPart> _automaticChildren, IGraphicalEditPart _host) {
+ boolean sameParentEditPart = mainEditPart.equals(_parentEditPart);
+ boolean sameHost = host.equals(_host);
+ boolean sameAllChildren = containsSameElements(allChildren, _allChildren);
+ boolean sameAutomaticChildren = containsSameElements(automaticChildren, _automaticChildren);
+ return !(sameParentEditPart && sameHost && sameAllChildren && sameAutomaticChildren);
+ }
+
+ /**
+ * Compare two list of {@link IGraphicalEditPart} elements and return true if it contains the same elements
+ *
+ * @param list1
+ * List of {@link IGraphicalEditPart}
+ * @param list2
+ * List of {@link IGraphicalEditPart}
+ * @return true is contains same elements
+ */
+ private boolean containsSameElements(List<IGraphicalEditPart> list1, List<IGraphicalEditPart> list2) {
+ return list1.containsAll(list2) && list2.containsAll(list1);
+ }
+
+ @Override
+ protected void closeNotitfication(IContext context) {
+ papyrusNotificationView.dispose();
+ notification.delete();
+ manager.removeChooseChildrenNotification(mainEditPart);
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseParentNotificationConfigurator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseParentNotificationConfigurator.java
new file mode 100644
index 00000000000..f7504e9a21c
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/ChooseParentNotificationConfigurator.java
@@ -0,0 +1,264 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.ui;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.diagram.common.groups.Messages;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeModelParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChooseParentNotificationCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.diagram.common.groups.core.ui.utils.CreatorUtils;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.IContext;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+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;
+
+/**
+ * ICompositor used to choose parent among a list. This IComposite handle graphical and model parent.
+ *
+ * @author adaussy
+ *
+ */
+public class ChooseParentNotificationConfigurator extends NotificationConfigurator {
+
+ /**
+ * List of availables parents
+ */
+ private List<IGraphicalEditPart> parents;
+
+ /**
+ * the mode to use this command with
+ */
+ private boolean mode;
+
+ /**
+ * buttons for children
+ */
+ private Map<Button, IGraphicalEditPart> childCheckBoxes;
+
+ /**
+ * Edit part of the children
+ */
+ private IGraphicalEditPart mainEditPart;
+
+ /**
+ * {@link EditPart} hosting the {@link EditPolicy}
+ */
+ private IGraphicalEditPart host;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parents
+ * all available parents (model of graphical {@link #mode}
+ * @param _childPart
+ * IGraphicalEditPart of the child (the child has to be already created)
+ * @param mode
+ * Choose between graphical and model
+ * Model : Change the model parent and the graphical parent
+ * Graphical : Change only the graphical parent
+ */
+ public ChooseParentNotificationConfigurator(List<IGraphicalEditPart> parents, IGraphicalEditPart _childPart, Boolean mode, IGraphicalEditPart getHost, PendingGroupNotificationsManager _manager, Mode messageMode, String label) {
+ super(_childPart, _manager, label, messageMode);
+ this.parents = parents;
+ childCheckBoxes = new HashMap<Button, IGraphicalEditPart>();
+ mainEditPart = _childPart;
+ this.mode = mode;
+ this.host = getHost;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator#createComposite(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.forms.widgets.FormToolkit)
+ *
+ * @param parent
+ * @param toolkit
+ * @return
+ */
+ public Composite createComposite(Composite parent, FormToolkit toolkit) {
+ if(toolkit == null) {
+ toolkit = new FormToolkit(parent.getDisplay());
+ }
+ Composite top = toolkit.createComposite(parent, SWT.NONE);
+ top.setLayout(new FormLayout());
+ FormText textLabel = toolkit.createFormText(top, false);
+ textLabel.setText(Messages.ChooseParentNotificationCommand_ChooseGraphicalParentMessage + CreatorUtils.getLabel(mainEditPart), false, true);
+ FormData data = new FormData();
+ textLabel.setLayoutData(data);
+ Control previousElement = textLabel;
+ /*
+ * Create for each parents a checkbox
+ */
+ createCheckBoxes(toolkit, top, previousElement);
+
+
+ return top;
+ }
+
+
+ public IGraphicalEditPart getChildPart() {
+ return mainEditPart;
+ }
+
+ /**
+ * Create for each parent a check box and select the default one
+ *
+ * @param toolkit
+ * @param top
+ * @param previousElement
+ */
+ private void createCheckBoxes(FormToolkit toolkit, Composite top, Control previousElement) {
+ FormData data;
+
+ for(IGraphicalEditPart parentEditPart : parents) {
+ String label = CreatorUtils.getLabel(parentEditPart);
+ Button checkBox = toolkit.createButton(top, label, SWT.RADIO);
+ EditPart childParent = mainEditPart.getParent();
+ if(childParent != null && childParent.equals(parentEditPart)) {
+ checkBox.setSelection(true);
+ } else {
+ checkBox.setSelection(false);
+ }
+ data = CreatorUtils.getFormDataUnder(previousElement);
+ checkBox.setLayoutData(data);
+ previousElement = checkBox;
+ childCheckBoxes.put(checkBox, parentEditPart);
+ // add dispose listener to remove from handled widgets
+ checkBox.addDisposeListener(new DisposeListener() {
+
+ /**
+ * Remove widget from handled ones
+ *
+ * @param e
+ * the dispose event
+ */
+ public void widgetDisposed(DisposeEvent e) {
+ childCheckBoxes.remove(e.widget);
+ }
+ });
+ //checkBox.addSelectionListener(
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#run(org.eclipse.papyrus.ui.toolbox.notification.builders.IContext)
+ *
+ * @param context
+ */
+ public void run(IContext context) {
+ IGraphicalEditPart newParent = null;
+ for(Button checkBoxButton : childCheckBoxes.keySet()) {
+ if(checkBoxButton.getSelection()) {
+ newParent = childCheckBoxes.get(checkBoxButton);
+ }
+ }
+ //If the system has found the edit part of the new parent
+ if(newParent != null) {
+ TransactionalEditingDomain editingDomain = mainEditPart.getEditingDomain();
+ /*
+ * Change the model parent if needed
+ */
+ changeModelParent(newParent, editingDomain);
+ /*
+ * Change the graphical parent
+ */
+ changeGraphicalParent(newParent, editingDomain);
+ }
+
+ /*
+ * Close the notification
+ */
+ closeNotitfication(context);
+ }
+
+ /**
+ * Change the graphical parent
+ *
+ * @param newParent
+ * the new graphical parent of the child
+ * @param editingDomain
+ * to create an transactionnal command
+ */
+ private void changeGraphicalParent(IGraphicalEditPart newParent, TransactionalEditingDomain editingDomain) {
+ String label = "Change graphical parent" + " of " + CreatorUtils.getLabel(mainEditPart) + " to " + CreatorUtils.getLabel(newParent);
+ ChangeGraphicalParentCommand reassignParent = new ChangeGraphicalParentCommand(editingDomain, label, newParent, mainEditPart, host);
+ //If the command is valid the system execute it
+ if(reassignParent != null && reassignParent.canExecute()) {
+ //Execute the command
+ editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(reassignParent));
+ }
+ }
+
+ /**
+ * Change the model parent if the current mode is model
+ *
+ * @param newParent
+ * New model parent of the child
+ * @param editingDomain
+ * to create the transactional command
+ */
+ private void changeModelParent(IGraphicalEditPart newParent, TransactionalEditingDomain editingDomain) {
+ if(mode == ChooseParentNotificationCommand.MODEL_MODE) {
+ EObject childObject = mainEditPart.resolveSemanticElement();
+ EObject parentObject = newParent.resolveSemanticElement();
+ if(parentObject != null && childObject != null) {
+ EReference ref = Utils.getContainmentEReference(parentObject.eClass(), childObject.eClass());
+ if(ref != null) {
+ Map<EObject, EReference> chilrendToMove = new HashMap<EObject, EReference>();
+ chilrendToMove.put(childObject, ref);
+ ChangeModelParentCommand reassignModelparent = new ChangeModelParentCommand(editingDomain, newParent, chilrendToMove, newParent);
+ //If the command is valid the system execute it
+ if(reassignModelparent != null && reassignModelparent.canExecute()) {
+ //Execute the command
+ editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(reassignModelparent));
+ }
+ }
+ } else {
+ org.eclipse.papyrus.diagram.common.groups.Activator.getDefault().getLog().log(new Status(Status.WARNING, org.eclipse.papyrus.diagram.common.groups.Activator.PLUGIN_ID, "One of the needed element is unavailable"));
+ }
+ }
+ }
+
+ @Override
+ protected void closeNotitfication(IContext context) {
+ papyrusNotificationView.dispose();
+ notification.delete();
+ manager.removeChooseParentNotification(mainEditPart);
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CompositeCreatorWithCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CompositeCreatorWithCommand.java
new file mode 100644
index 00000000000..11b7c2ce885
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/CompositeCreatorWithCommand.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.IContext;
+
+/**
+ * The CompositeCreator with command is an abstract implementation of ICompositeCreator which take cares of storing a command which evolves with the
+ * decisions the user takes in the built notification.
+ *
+ * @author vhemery
+ */
+public abstract class CompositeCreatorWithCommand implements ICompositeCreator {
+
+ /** the commands to execute at notification close */
+ private Map<Object, Command> commandsMap = new HashMap<Object, Command>();
+
+ /**
+ * Add a command which will be executed as result of the notification. If a command already exist for that key, it will be replaced.
+ * If cmd is null, any existing command for the given key is removed.
+ *
+ * @param key
+ * the object to use as a key for the command (may be null)
+ * @param cmd
+ * the command to store
+ */
+ protected void addResultingCommandForObject(Object key, Command cmd) {
+ if(cmd != null) {
+ commandsMap.put(key, cmd);
+ } else {
+ commandsMap.remove(key);
+ }
+ }
+
+ /**
+ * Get the command to execute as result of the notification
+ *
+ * @return command to execute
+ */
+ public Command getResultingCommand() {
+ if(!commandsMap.isEmpty()) {
+ return new CompoundCommand(new ArrayList<Command>(commandsMap.values()));
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the runnable action to run the resulting command.
+ * In case of an asynchronous action, a command will be executed.
+ * In case of a synchronous action, the command is not executed yet and must be recovered with {@link #getResultingCommand()}.
+ *
+ * @param isAsynchronous
+ * true if the action is asynchronous
+ *
+ * @return notification runnable
+ */
+ public NotificationRunnable getCommandRunner(final boolean isAsynchronous) {
+ return new NotificationRunnable() {
+
+ /**
+ * Run the stored resulting commands
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#run(org.eclipse.papyrus.ui.toolbox.notification.builders.IContext)
+ * @param context
+ * running context
+ */
+ public void run(IContext context) {
+ if(isAsynchronous) {
+ Command cmd = getResultingCommand();
+ if(cmd != null && cmd.canExecute()) {
+ cmd.execute();
+ }
+ }
+ removeNotification();
+ }
+
+ /**
+ * Get the action label
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#getLabel()
+ * @return stirng label
+ */
+ public String getLabel() {
+ return getRunLabel();
+ }
+ };
+ }
+
+ /**
+ * Remove the notification using {@link PendingGroupNotificationsManager} and the appropriate key
+ */
+ abstract protected void removeNotification();
+
+ /**
+ * Get the run action label
+ *
+ * @return string label
+ */
+ abstract protected String getRunLabel();
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/NotificationConfigurator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/NotificationConfigurator.java
new file mode 100644
index 00000000000..ef70395136d
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/NotificationConfigurator.java
@@ -0,0 +1,157 @@
+package org.eclipse.papyrus.diagram.common.groups.core.ui;
+
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.papyrus.diagram.common.groups.core.GroupNotificationBuilderFactory;
+import org.eclipse.papyrus.diagram.common.groups.core.PendingGroupNotificationsManager;
+import org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator;
+import org.eclipse.papyrus.ui.toolbox.notification.INotification;
+import org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.IContext;
+import org.eclipse.papyrus.ui.toolbox.notification.builders.NotificationBuilder;
+import org.eclipse.papyrus.ui.toolbox.notification.view.AbstractInsideComposite;
+import org.eclipse.papyrus.ui.toolbox.notification.view.PapyrusNotificationView;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+public abstract class NotificationConfigurator implements ICompositeCreator, NotificationRunnable {
+
+ public enum Mode {
+ QUESTION_MODE, WARNING_MODE
+ }
+
+ /**
+ * Instance of the {@link PendingGroupNotificationsManager} for tue current diagram
+ */
+ protected PendingGroupNotificationsManager manager;
+
+ /**
+ * {@link NotificationBuilder}
+ */
+ protected NotificationBuilder notificationBuilder;
+
+ /**
+ * {@link INotification} for choosing children
+ */
+ protected INotification notification;
+
+ /**
+ * View of the Papyrus notification view
+ */
+ protected AbstractInsideComposite papyrusNotificationView;
+
+ /**
+ * EditPart about which the notification is about
+ * (e.g Parent in case of ChooseChildrenNotificationConfigurator)
+ */
+ protected IGraphicalEditPart mainEditPart;
+
+ /**
+ * Label of the notification
+ */
+ private String label;
+
+ public NotificationConfigurator(IGraphicalEditPart _mainEdipart, PendingGroupNotificationsManager _manager, String _label, Mode mode) {
+ this.mainEditPart = _mainEdipart;
+ this.manager = _manager;
+ this.label = _label;
+ switch(mode) {
+ case WARNING_MODE:
+ notificationBuilder = GroupNotificationBuilderFactory.getWarningBuilder(_label);
+ break;
+ case QUESTION_MODE:
+ default:
+ notificationBuilder = GroupNotificationBuilderFactory.getQuestionBuilder(_label);
+ break;
+ }
+
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#getLabel()
+ *
+ * @return
+ */
+ public String getLabel() {
+ return label;
+ }
+
+
+
+ public void setMainEditPart(IGraphicalEditPart mainEditPart) {
+ this.mainEditPart = mainEditPart;
+ }
+
+ /**
+ * Run the notification
+ *
+ * @return
+ */
+ public INotification runConfigurator() {
+ notification = notificationBuilder.setComposite(this).addAction(this).run();
+ if(notification != null) {
+ if(manager != null) {
+ manager.storeNotification(this);
+ }
+ try {
+ IViewPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(PapyrusNotificationView.ID);
+ if(part instanceof PapyrusNotificationView) {
+ PapyrusNotificationView view = (PapyrusNotificationView)part;
+ Collection<NotificationRunnable> singleton = new ArrayList<NotificationRunnable>(1);
+ singleton.add(this);
+ AbstractInsideComposite viewCompo = view.setComposite(this, getLabel(), singleton);
+ papyrusNotificationView = viewCompo;
+ viewCompo.setINotification(notification);
+
+
+ }
+ } catch (PartInitException e) {
+ // do not log in notification view
+ }
+ }
+ return notification;
+ }
+
+ /**
+ * Get the current notification
+ *
+ * @return the notification
+ */
+ public INotification getNotification() {
+ return notification;
+ }
+
+
+
+ /**
+ * Close the notification
+ *
+ * @param context
+ *
+ */
+ protected abstract void closeNotitfication(IContext context);
+
+
+ /**
+ * Close the notification
+ */
+ public void closeNotification() {
+ closeNotitfication(null);
+ }
+
+ /**
+ * Get the {@link IGraphicalEditPart} of the Notification
+ *
+ * @return
+ */
+ public IGraphicalEditPart getMainEditPart() {
+ return mainEditPart;
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/utils/CreatorUtils.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/utils/CreatorUtils.java
new file mode 100644
index 00000000000..0ab8fbb82dc
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/ui/utils/CreatorUtils.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.ui.utils;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.uml2.uml.edit.providers.UMLItemProviderAdapterFactory;
+
+/**
+ * Provides usefull utility methods for ICompositeCreator instances
+ *
+ * @author vhemery
+ */
+public class CreatorUtils {
+
+ /** The offset to use for form data */
+ private static final int OFFSET = 5;
+
+ /** The adapter factory to use as label provider */
+ private static AdapterFactoryLabelProvider adapterFactory = null;
+
+ /**
+ * Get the form layout data to place element at top of the parent composite
+ *
+ * @return form data
+ */
+ public static FormData getTopFormData() {
+ FormData data = new FormData();
+ data.right = new FormAttachment(100, -OFFSET);
+ data.left = new FormAttachment(0, OFFSET);
+ data.top = new FormAttachment(0, OFFSET);
+ return data;
+ }
+
+ /**
+ * Get the form layout data to place element under another
+ *
+ * @param upperControl
+ * control under which the element must be located
+ * @return form data
+ */
+ public static FormData getFormDataUnder(Control upperControl) {
+ FormData data = new FormData();
+ data.right = new FormAttachment(100, -OFFSET);
+ data.left = new FormAttachment(0, OFFSET);
+ data.top = new FormAttachment(upperControl, OFFSET);
+ return data;
+ }
+
+ /**
+ * Get the form layout data to place element under another, aligned on the right of the parent composite
+ *
+ * @param upperControl
+ * control under which the element must be located
+ * @return form data
+ */
+ public static FormData getFormDataRightAlignedUnder(Control upperControl) {
+ FormData data = new FormData();
+ data.right = new FormAttachment(100, -OFFSET);
+ data.top = new FormAttachment(upperControl, OFFSET);
+ return data;
+ }
+
+ /**
+ * Get the label of a graphical edit part
+ *
+ * @param editPart
+ * the input part
+ * @return the string label
+ */
+ public static String getLabel(IGraphicalEditPart editPart) {
+ EObject eObject = editPart.resolveSemanticElement();
+ return getCustomLabelProvider().getText(eObject);
+ }
+
+ /**
+ * Gets the custom label provider that parses label for EClass
+ *
+ * @return the custom label provider
+ */
+ public static ILabelProvider getCustomLabelProvider() {
+ if(adapterFactory == null) {
+ adapterFactory = new AdapterFactoryLabelProvider(new UMLItemProviderAdapterFactory()) {
+
+ /**
+ * Override label provider for EClass
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object object) {
+ String text = super.getText(object);
+ if(object instanceof EClass) {
+ return text.substring(0, text.indexOf("[") - 1);
+ } else {
+ return text;
+ }
+ }
+ };
+ }
+ return adapterFactory;
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/DefaultModelParent.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/DefaultModelParent.java
new file mode 100644
index 00000000000..c03656c237a
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/DefaultModelParent.java
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.utils;
+
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+
+/**
+ * Class used as result of getDefaultModelParent.
+ * Object will care 3 information:
+ * The IGraphicalEditPart of the default model parent
+ * The ERefence with which it will contain the child
+ *
+ * @author adaussy
+ *
+ */
+
+public class DefaultModelParent {
+
+ /**
+ * The IGraphicalEditPart of the defautl model parent
+ */
+ private IGraphicalEditPart iGraphicalEditPart;
+
+ /**
+ * The ERefence with which it will contain the child
+ */
+ private EReference eReference;
+
+ public DefaultModelParent(IGraphicalEditPart iGraphicalEditPart, EReference eReference) {
+ super();
+ this.iGraphicalEditPart = iGraphicalEditPart;
+ this.eReference = eReference;
+ }
+
+
+ public IGraphicalEditPart getiGraphicalEditPart() {
+ return iGraphicalEditPart;
+ }
+
+
+
+ public EReference geteReference() {
+ return eReference;
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/Utils.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/Utils.java
new file mode 100644
index 00000000000..d53644b19d1
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/core/utils/Utils.java
@@ -0,0 +1,1048 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.core.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.RoundedRectangle;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.LayerConstants;
+import org.eclipse.gef.editparts.LayerManager;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.notation.Bounds;
+import org.eclipse.gmf.runtime.notation.LayoutConstraint;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.commands.wrappers.GEFtoEMFCommandWrapper;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeModelParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+import org.eclipse.papyrus.diagram.common.groups.utils.GraphicalAndModelElementComparator;
+import org.eclipse.papyrus.diagram.common.groups.utils.GraphicalAndModelElementComparator.Mode;
+
+
+/**
+ * This class provides utility methods useful for the group framework.
+ *
+ * @author vhemery and adaussy
+ */
+public class Utils {
+
+ /**
+ * Find the containers which may contain an edit part in the given bounds.
+ *
+ * @param bounds
+ * the new or old bounds of the item
+ * @param diagramPart
+ * the diagram edit part
+ * @return the list of edit parts that are registered through the group framework and that can contain an element within the given bounds
+ */
+ public static List<IGraphicalEditPart> findPossibleParents(Rectangle bounds, DiagramEditPart diagramPart) {
+ if(diagramPart == null) {
+ return Collections.emptyList();
+ }
+ Set<IGraphicalEditPart> groupParts = new HashSet<IGraphicalEditPart>();
+ //For all object in diagram, find edit parts
+ for(Object view : diagramPart.getViewer().getEditPartRegistry().keySet()) {
+ if(view instanceof View) {
+ Object editpart = diagramPart.getViewer().getEditPartRegistry().get(view);
+ if(editpart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart part = (IGraphicalEditPart)editpart;
+ //If this group is handled by the group framework
+ if(GroupContainmentRegistry.isContainerConcerned(part)) {
+ //recover group descriptor of this part
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(part);
+ //Look if I can get the Eclass from the IdoneContainer
+ //And I look if its contain the element we want it to be compared with
+ if(desc.getContentArea(part).contains(bounds)) {
+ groupParts.add(part);
+ }
+ }
+ }
+ }
+ }
+ return new ArrayList<IGraphicalEditPart>(groupParts);
+ }
+
+ /**
+ * Find containers which may be chosen as graphical and as model parent of the element which has already been created
+ *
+ * @param graphicalParentsToComplete
+ * an empty list that will be filled with edits part of available graphical parents (e.g. new ArrayList())
+ * @param modelParentsToComplete
+ * an empty list that will be filled with edits part of available graphical parents (e.g. new ArrayList())
+ * @param childPart
+ * Edit part of the element we want to find out which may be its containers
+ * @param doTransalte
+ * if true compute the list of all graphical and model parent after moving and false compute the list before moving
+ * @return true if succeed
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean createComputedListsOfParents(List<IGraphicalEditPart> graphicalParentsToComplete, List<IGraphicalEditPart> modelParentsToComplete, IGraphicalEditPart childPart, ChangeBoundsRequest request, boolean doTransalte) {
+ Collection<View> diagramViews = new ArrayList<View>(childPart.getViewer().getEditPartRegistry().keySet());
+ Object _elementView = childPart.getModel();
+ if(_elementView instanceof View) {
+ diagramViews.remove(_elementView);
+ View myGroupView = (View)_elementView;
+ withdrawGraphicalSonsOf(diagramViews, myGroupView);
+ }
+ Rectangle bounds = null;
+ EClass childType = null;
+ if(childPart != null) {
+ bounds = Utils.getAbsoluteBounds(childPart).getCopy();
+ childType = childPart.resolveSemanticElement().eClass();
+ }
+ if(doTransalte) {
+ bounds = request.getTransformedRectangle(bounds);
+ }
+ return createComputedListsOfParents(graphicalParentsToComplete, modelParentsToComplete, bounds, childType, diagramViews, childPart);
+ }
+
+ /**
+ * Find containers which may be chosen as graphical and as model parent of the element (after creation)
+ *
+ * @param graphicalParentsToComplete
+ * an empty list that will be filled with edits part of available graphical parents (e.g. new ArrayList())
+ * @param modelParentsToComplete
+ * an empty list that will be filled with edits part of available graphical parents (e.g. new ArrayList())
+ * @param creationRequest
+ * request of creation
+ * @param anyPart
+ * An edit part to get the viewer
+ * @param child
+ * The EClass of the element to create
+ * @param elementName
+ * Name of the element to be created (name used to look for default size FIXME)
+ * @return true if succeed
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean createComputedListsOfParents(List<IGraphicalEditPart> graphicalParentsToComplete, List<IGraphicalEditPart> modelParentsToComplete, CreateViewAndElementRequest creationRequest, IGraphicalEditPart anyPart, EClass child) {
+ Collection<View> diagramViews = new ArrayList<View>(anyPart.getViewer().getEditPartRegistry().keySet());
+ Dimension size = creationRequest.getSize();
+ //FIXME : Add a correct default size
+ // If size == null then a default size is used to create the bounds of the new elements
+ if(size == null || size.isEmpty()) {
+ size = new Dimension(0, 0);
+ }
+ Rectangle bounds = new Rectangle(creationRequest.getLocation(), size);
+ return createComputedListsOfParents(graphicalParentsToComplete, modelParentsToComplete, bounds, child, diagramViews, anyPart);
+ }
+
+ /**
+ * Find containers which may be chosen as graphical and as model parent of the element to create
+ *
+ * @param graphicalParentsToComplete
+ * an empty list that will be filled with edits part of available graphical parents (e.g. new ArrayList())
+ * @param modelParentsToComplete
+ * an empty list that will be filled with edits part of available model parents e.g. new ArrayList())
+ * @param bounds
+ * Bounds of the element
+ * @param request
+ * createElementRequest of the current request
+ * @param views
+ * Collection of view to iteration on
+ * @param anyPart
+ * an edit part of the diagram to get the viewer
+ * @return true if successful
+ */
+ private static boolean createComputedListsOfParents(List<IGraphicalEditPart> graphicalParentsToComplete, List<IGraphicalEditPart> modelParentsToComplete, Rectangle bounds, EClass child, Collection<View> views, IGraphicalEditPart anyPart) {
+ if(views.isEmpty()) {
+ return false;
+ }
+ for(Object view : views) {
+ if(view instanceof View) {
+ Object editpart = anyPart.getViewer().getEditPartRegistry().get(view);
+ if(editpart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart part = (IGraphicalEditPart)editpart;
+ if(GroupContainmentRegistry.isContainerConcerned(part)) {
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(part);
+ //Check if the current part contains the element
+ //FIXME replace this piece of code by isItVisualyContained
+ if(desc.getContentArea(part).contains(bounds)) {
+ if(child instanceof EClass) {
+ if(desc.canIBeModelParentOf(child)) {
+ // If an edit part can be a model parent then is also a possible graphical parent
+ graphicalParentsToComplete.add(part);
+ modelParentsToComplete.add(part);
+ } else {
+ if(desc.canIBeGraphicalParentOf(child)) {
+ graphicalParentsToComplete.add(part);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ //Try to reduce the number of available parents by removing
+ if(graphicalParentsToComplete.size() > 1)
+ withdrawUselessAncestorsElements(graphicalParentsToComplete, Mode.GRAPHICAL_AND_MODEL);
+ if(modelParentsToComplete.size() > 1)
+ withdrawUselessAncestorsElements(modelParentsToComplete, Mode.MODEL);
+ //FIXME Sort the two list in order to have the most relevant parent first (lowest surface )
+ return true;
+ }
+
+ /**
+ * This method complete the list childsToComplete to add element which are visually contained in the element in creation "parent" and which can
+ * be graphical children of this new elements
+ *
+ * @param childsToComplete
+ * Empty list which will contain in the newly created element "parent" and which can be graphical children of this new elements
+ * @param creationRequest
+ * request of creation
+ * @param anyPart
+ * An edit part to get the viewer
+ * @param descriptor
+ * Descriptor of the element in creation
+ * @param ElementTypeName
+ * Name of the element to be created (name used to look for default size FIXME)
+ * @return true if succeed
+ */
+ public static boolean createComputedListsOfVisualYRelatedElements(List<IGraphicalEditPart> childsToComplete, CreateViewAndElementRequest creationRequest, IGraphicalEditPart anyPart, AbstractContainerNodeDescriptor descriptor) {
+ Collection<View> diagramViews = new ArrayList<View>(anyPart.getViewer().getEditPartRegistry().keySet());
+ Dimension size = creationRequest.getSize();
+ //FIXME : Add a correct default size
+ // If size == null then a default size is used to create the bounds of the new elements
+ if(size == null || size.isEmpty()) {
+ size = new Dimension(0, 0);
+ }
+ Rectangle bounds = new Rectangle(creationRequest.getLocation(), size);
+ createComputedListsOfVisualyRelatedElements(childsToComplete, bounds, descriptor, diagramViews, anyPart);
+ return true;
+ }
+
+ /**
+ * This method complete the list childsToComplete to add element which are visually contained in the element which is moving ("parent") and which
+ * can
+ * be graphical children of this new elements
+ *
+ * @param childsToComplete
+ * Empty list which will contain in the newly created element "parent" and which can be graphical children of this new elements
+ * @param request
+ * {@link ChangeBoundsRequest}
+ * @param parentPart
+ * {@link IGraphicalEditPart} of the parent
+ * @param descriptor
+ * {@link AbstractContainerNodeDescriptor} of the parent
+ * @return true is succeed
+ */
+ public static boolean createComputedListsOfVisuallyRelatedElements(List<IGraphicalEditPart> childsToComplete, ChangeBoundsRequest request, IGraphicalEditPart parentPart, AbstractContainerNodeDescriptor descriptor, boolean doTransalte) {
+ Collection<View> diagramViews = new ArrayList<View>(parentPart.getViewer().getEditPartRegistry().keySet());
+ diagramViews.remove(parentPart.getModel());
+ Rectangle bounds = null;
+
+ IGraphicalEditPart compartmentEditPart = (IGraphicalEditPart)Utils.getCompartementEditPartFromMainEditPart(parentPart.getViewer().getEditPartRegistry(), parentPart);
+ if(compartmentEditPart == null) {
+ compartmentEditPart = parentPart;
+ }
+ if(parentPart != null) {
+ bounds = Utils.getAbsoluteBounds(compartmentEditPart).getCopy();
+ }
+ if(doTransalte) {
+ //bounds.translate(request.getMoveDelta());
+ bounds = request.getTransformedRectangle(bounds);
+ }
+ createComputedListsOfVisualyRelatedElements(childsToComplete, bounds, descriptor, diagramViews, parentPart);
+ return true;
+ }
+
+ /***
+ * Compute a list of all group which include the bounds of my element which has been moved with the following request
+ *
+ * @param element
+ * Element which we can know the groups which it intersect
+ * @param request
+ * {@link ChangeBoundsRequest} of the moving group
+ * @param doTranslate
+ * if true translate the bound of the element. (used to find the difference between element before and after the command)
+ * @return The list of {@link IGraphicalEditPart} group that which has their compartment edit part which intersect the compartment of my
+ */
+ public static List<IGraphicalEditPart> createComputeListsOfAllGroupContainerVisually(IGraphicalEditPart element, ChangeBoundsRequest request, boolean doTranslate, IGraphicalEditPart movingParent) {
+ List<IGraphicalEditPart> result = new ArrayList<IGraphicalEditPart>();
+ EditPartViewer viewer = element.getViewer();
+ Map editPartRegistry = null;
+ if(viewer != null) {
+ editPartRegistry = viewer.getEditPartRegistry();
+ }
+ // Test on entrances
+ if(editPartRegistry == null || element == null) {
+ return null;
+ }
+ //Get the compartment edit part
+ IGraphicalEditPart myCompartmentEditPart = (IGraphicalEditPart)getCompartementEditPartFromMainEditPart(editPartRegistry, element);
+ Rectangle myBounds = null;
+ /*
+ * Find the bounds of the compartment if none use the figure bounds
+ */
+ if(myCompartmentEditPart != null) {
+ myBounds = getAbsoluteBounds(myCompartmentEditPart).getCopy();
+ } else {
+ myBounds = getAbsoluteBounds(element).getCopy();
+ }
+ /*
+ * If use the translated figure use as bounds for the childs its bounds translated with the delta move
+ */
+ if(doTranslate) {
+ myBounds = myBounds.translate(request.getMoveDelta());
+ }
+
+ Collection<View> diagramViews = new ArrayList<View>(editPartRegistry.keySet());
+ Object _elementView = element.getModel();
+ diagramViews.remove(_elementView);
+ /*
+ * Withdraw from the collection of element all elements which are graphical child in myGroupView
+ */
+ if(_elementView instanceof View) {
+ View myGroupView = (View)_elementView;
+ withdrawGraphicalSonsOf(diagramViews, myGroupView);
+ }
+
+ /*
+ * For all graphical edits parts try to know if it visually contained the child
+ */
+ for(Object view : diagramViews) {
+ if(view instanceof View) {
+ Object editpart = editPartRegistry.get(view);
+ if(editpart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart part = (IGraphicalEditPart)editpart;
+ IGraphicalEditPart partCompartment = (IGraphicalEditPart)getCompartementEditPartFromMainEditPart(editPartRegistry, part);
+ if(GroupContainmentRegistry.isContainerConcerned(part) && partCompartment != null) {
+ Rectangle partBounds = getAbsoluteBounds(partCompartment);
+ if((part.getParent().equals(movingParent) || partCompartment.equals(movingParent)) && doTranslate) {
+ partBounds = request.getTransformedRectangle(partBounds);
+ }
+ if(partBounds.contains(myBounds)) {
+ result.add(part);
+ }
+ }
+ }
+ }
+ }
+
+
+ return result;
+ }
+
+ /**
+ * Function which withdraw from a list of view all view which are descendant of the myView parameter
+ * (This function is called recursively
+ *
+ * @param views
+ * List of the view
+ * @param myView
+ * The view we want to remove the descendant
+ */
+ private static void withdrawGraphicalSonsOf(Collection<View> views, View myView) {
+ for(Object o : myView.getChildren()) {
+ if(o instanceof View) {
+ View childView = (View)o;
+ withdrawGraphicalSonsOf(views, childView);
+ views.remove(childView);
+ }
+
+ }
+ }
+
+ /**
+ * Find containers which may be chosen as graphical and as model parent of the element
+ *
+ * @param childsToComplete
+ * Empty list which will contain in the newly created element "parent" and which can be graphical children of this new elements
+ * @param parentsBounds
+ * Bounds of the element
+ * @param descriptors
+ * Descriptor of the element in creation
+ * @param views
+ * Collection of view to iteration on
+ * @param anyPart
+ * an edit part of the diagram to get the viewer
+ * @return true if succeed
+ */
+ private static boolean createComputedListsOfVisualyRelatedElements(List<IGraphicalEditPart> childsToComplete, Rectangle parentsBounds, AbstractContainerNodeDescriptor descriptor, Collection<View> views, IGraphicalEditPart anyPart) {
+ /*
+ * 1 - Compute the EClass(s) which the element can be parent of : listEclass
+ * 2 - Iterate on views : v
+ * 2.1 - If v correspond to a main editPart : part
+ * 2.1.1 - If v correspond to a a EClass which belong to listEclass
+ * 2.1.1.1 - If part is visually contained is the parent then add to the list
+ * 3 - Withdraw useless elements
+ */
+ //Set<AbstractContainerNodeDescriptor> descriptors = GroupContainmentRegistry.getDescriptorsWithContainerEClass(parentEclass);
+ List<EClass> possibleChildrenEClass = new ArrayList<EClass>(descriptor.getPossibleGraphicalChildren());
+ if(!possibleChildrenEClass.isEmpty()) {
+ for(Object view : views) {
+ if(view instanceof View) {
+ View childView = (View)view;
+ EClass childEclass = (childView.getElement().eClass());
+ Object editpart = anyPart.getViewer().getEditPartRegistry().get(childView);
+ if(editpart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart part = (IGraphicalEditPart)editpart;
+ if(isMainEditPart(part)) {
+ for(EClass possibleChild : possibleChildrenEClass) {
+ if(possibleChild.isSuperTypeOf(childEclass)) {
+ if(isItVisualyContained(parentsBounds, part)) {
+ childsToComplete.add(part);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(childsToComplete.size() > 1)
+ withdrawUselessDescendantElements(childsToComplete, Mode.GRAPHICAL_AND_MODEL);
+ }
+
+ return true;
+ }
+
+ /**
+ * This methods is used to know if an edit part is contained in a rectangle
+ *
+ * @param parentBounds
+ * Rectangle of the parent
+ * @param child
+ * IGraphicalEditPart of the element we want to test
+ * @return true if the bounds of child are contained in parentsBounds
+ */
+ private static boolean isItVisualyContained(Rectangle parentBounds, IGraphicalEditPart child) {
+
+ if(child.getParent() instanceof IGraphicalEditPart) {
+ // an edit part is considered the "main" edit part of an element if it is not contained in an edit part of the same element (e.g. not a label nor a compartment)
+ // Rectangle bounds = child.getFigure().getBounds().getCopy();
+ //
+ // ((IGraphicalEditPart)child.getParent()).getFigure().translateToAbsolute(bounds);
+
+ Rectangle bounds = Utils.getAbsoluteBounds(child);
+ if(bounds != null) {
+ if(parentBounds.contains(bounds)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if the edit part is the main editPart of a model element (e.g the label is not the main edit part of an activityPartition
+ *
+ * @param part
+ * IGraphicalEditPart to test
+ * @return
+ */
+ public static boolean isMainEditPart(IGraphicalEditPart part) {
+ EObject currentElement = part.resolveSemanticElement();
+ EditPart parentEditPart = part.getParent();
+ if(parentEditPart instanceof IGraphicalEditPart) {
+ return !currentElement.equals(((IGraphicalEditPart)parentEditPart).resolveSemanticElement());
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * This method remove all elements from the list which have a parent in the (graphical model) or model in the list
+ *
+ * @param listToModify
+ * List of elements (IGraphicalEditPart
+ * @param mode
+ * if GraphicalAndModelElementComparator.MODEL then it only take care of model parent if
+ * GraphicalAndModelElementComparator.GRAPHICAL_AND_MODEL it take care of graphical and logical relationship
+ * @return true if succeed
+ */
+ private static void withdrawUselessAncestorsElements(List<IGraphicalEditPart> listToModify, Mode mode) {
+ if(!listToModify.isEmpty()) {
+
+ GraphicalAndModelElementComparator comparator = new GraphicalAndModelElementComparator(listToModify.get(0));
+ //Select the comparator mode
+
+ comparator.setMode(mode);
+
+ /**
+ * Keep in the list only elements which which have no smaller element ( with this comparator)
+ *
+ */
+ for(int element = 0; element < listToModify.size(); element++) {
+ for(int elementToCompare = element + 1; elementToCompare < listToModify.size(); elementToCompare++) {
+ int compare = comparator.compare((IGraphicalEditPart)listToModify.get(element), (IGraphicalEditPart)listToModify.get(elementToCompare));
+ if(compare < 0) {
+ listToModify.remove(element);
+ element--;
+ elementToCompare = listToModify.size();
+
+ } else if(compare > 0) {
+ listToModify.remove(elementToCompare);
+ elementToCompare--;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This method will withdraw all EObject directly referenced by object which are also referenced by one of its parents (parent by reference and
+ * parent by containment)
+ *
+ * @param object
+ */
+ public static void withDrawRedundantElementReferenced(EObject object) {
+ /*
+ * Algo :
+ * 1 - Select all references which are Group Framework concerned and which represent a reference to a parent
+ * 2 - Create a Set directlyReferencedByElement of EObject directly referenced by object
+ * 3 - Iterate thought parents to see if one of them also point at an element of directlyReferencedByElement
+ */
+ /*
+ * 1 - Select all references which are Group Framework concerned and which represent a reference to a parent
+ */
+ Set<EReference> groupFrameworkReferences = GroupContainmentRegistry.getAllERefencesFromNodeToGroup();
+ HashMap<EObject, EReference> referencingGroupsAndTheirRelation = new HashMap<EObject, EReference>();
+ Set<EObject> elementToVosit = new HashSet<EObject>();
+ for(EReference ref : groupFrameworkReferences) {
+ if(object.eClass().getEAllReferences().contains(ref)) {
+ // list of groups containing the object
+ List<EObject> groups;
+ if(ref.isMany()) {
+ groups = (List<EObject>)object.eGet(ref);
+ } else {
+ groups = Collections.singletonList((EObject)object.eGet(ref));
+ }
+ if(!ref.isContainment()) {
+ /*
+ * 2 - Create a Set directlyReferencedByElement of EObject directly referenced by object
+ */
+ for(EObject element : groups) {
+ if(!referencingGroupsAndTheirRelation.containsKey(element) && !ref.isDerived()) {
+ referencingGroupsAndTheirRelation.put(element, ref);
+ }
+ }
+ }
+ for(EObject group : groups) {
+ if(group != null) {
+ elementToVosit.add(group);
+ }
+ }
+ }
+ }
+ Set<EObject> elementAlreadyVisited = new HashSet<EObject>();
+ for(EObject visitingElement : elementToVosit) {
+ withDrawRedundantElementReferenced(object, groupFrameworkReferences, referencingGroupsAndTheirRelation, elementAlreadyVisited, visitingElement);
+ }
+ }
+
+ /**
+ * This method will withdraw all EObject directly referenced by object which are also referenced by one of its parents (parent by reference and
+ * parent by containment). This method is called recursively
+ *
+ * @param originalEObject
+ * The EObject on which you want to check the reference
+ * @param groupFrameworkReferences
+ * All the EReference which are used on the groupFramework and which represent a relation from a element to its parent
+ * @param directlyReferencedByElement
+ * Set of elements which are directly referenced by the original element
+ * @param elementAlreadyVisited
+ * Set of element already visited. Used to avoid infinite loop
+ * @param visitingElement
+ * The current element which is being visited
+ */
+ private static void withDrawRedundantElementReferenced(EObject originalEObject, Set<EReference> groupFrameworkReferences, Map<EObject, EReference> directlyReferencedByElement, Set<EObject> elementAlreadyVisited, EObject visitingElement) {
+ if(visitingElement != null) {
+ elementAlreadyVisited.add(visitingElement);
+ for(EReference ref : groupFrameworkReferences) {
+ if(visitingElement != null) {
+ if(visitingElement.eClass().getEAllReferences().contains(ref)) {
+ List<EObject> groups;
+ if(ref.isMany()) {
+ groups = (List<EObject>)visitingElement.eGet(ref);
+ } else {
+ groups = Collections.singletonList((EObject)visitingElement.eGet(ref));
+ }
+ for(EObject currentElementParentGroup : groups) {
+ //If it belong to the directly referenced element then
+ if(directlyReferencedByElement.containsKey(currentElementParentGroup)) {
+ withdrawEObjectFromReference(originalEObject, currentElementParentGroup, directlyReferencedByElement.get(currentElementParentGroup));
+ // parents already handled in the first recursion (as direct parent group)
+ } else if(elementAlreadyVisited.contains(currentElementParentGroup)) {
+ // element already met, avoid infinite loop
+ org.eclipse.papyrus.diagram.common.groups.Activator.getDefault().getLog().log(new Status(Status.WARNING, org.eclipse.papyrus.diagram.common.groups.Activator.PLUGIN_ID, "There is a circle element reference"));
+ } else {
+ //else iterate recursively also on this group's parents
+ withDrawRedundantElementReferenced(originalEObject, groupFrameworkReferences, directlyReferencedByElement, elementAlreadyVisited, currentElementParentGroup);
+ //elementToVosit.add(currentCompareElement);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is used to with an element of a reference
+ *
+ * @param source
+ * EObject from which the reference start
+ * @param destination
+ * EObject to which the reference start
+ * @param ref
+ * EReference
+ */
+ private static void withdrawEObjectFromReference(EObject source, EObject destination, EReference ref) {
+ if(ref != null && source != null && destination != null) {
+ if(ref != null && ref.isMany()) {
+ Collection<EObject> collection = (Collection<EObject>)source.eGet(ref);
+ if(collection.contains(destination)) {
+ collection.remove(destination);
+ }
+ } else if(ref != null && !ref.isMany()) {
+ source.eUnset(ref);
+ }
+ }
+ }
+
+ /**
+ * This method remove all elements from the list which have a descendant in the (graphical model) or model in the list
+ *
+ * @param listToModify
+ * List of elements (IGraphicalEditPart
+ * @param mode
+ * if GraphicalAndModelElementComparator.MODEL then it only take care of model parent if
+ * GraphicalAndModelElementComparator.GRAPHICAL_AND_MODEL it take care of graphical and logical relationship
+ * @return true if succeed
+ */
+ private static boolean withdrawUselessDescendantElements(List<IGraphicalEditPart> listToModify, Mode mode) {
+
+ if(!listToModify.isEmpty()) {
+
+ GraphicalAndModelElementComparator comparator = new GraphicalAndModelElementComparator(listToModify.get(0));
+ //Select the comparator mode
+ comparator.setMode(mode);
+ for(int element = 0; element < listToModify.size(); element++) {
+ for(int elementToCompare = element + 1; elementToCompare < listToModify.size(); elementToCompare++) {
+ int compare = comparator.compare((IGraphicalEditPart)listToModify.get(element), (IGraphicalEditPart)listToModify.get(elementToCompare));
+ if(compare > 0) {
+ listToModify.remove(element);
+ element--;
+ elementToCompare = listToModify.size();
+
+ } else if(compare < 0) {
+ listToModify.remove(elementToCompare);
+ elementToCompare--;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+
+
+
+ /**
+ * Find the children edit parts which may be contained by the group in the given bounds.
+ *
+ * @param contentArea
+ * the new or old content area the group
+ * @param groupEditPart
+ * the group edit part
+ * @param diagramPart
+ * the diagram edit part
+ * @return the list of edit parts that are within the given bounds and which element can be children according to the group framework
+ */
+ public static List<IGraphicalEditPart> findPossibleChildren(Rectangle contentArea, IGraphicalEditPart groupEditPart, DiagramEditPart diagramPart) {
+ AbstractContainerNodeDescriptor descriptor = GroupContainmentRegistry.getContainerDescriptor(groupEditPart);
+ if(diagramPart == null || descriptor == null) {
+ return Collections.emptyList();
+ }
+ Set<IGraphicalEditPart> groupParts = new HashSet<IGraphicalEditPart>();
+ for(Object view : diagramPart.getViewer().getEditPartRegistry().keySet()) {
+ if(view instanceof View) {
+ Object editpart = diagramPart.getViewer().getEditPartRegistry().get(view);
+ if(editpart instanceof IGraphicalEditPart && editpart instanceof IPrimaryEditPart && !groupEditPart.equals(editpart)) {
+ IGraphicalEditPart part = (IGraphicalEditPart)editpart;
+ // check bounds
+ boolean boundsOK = false;
+ if(groupEditPart.getChildren().contains(editpart)) {
+ // graphically contained part will follow the move.
+ boundsOK = true;
+ } else {
+ Rectangle figBounds = part.getFigure().getBounds().getCopy();
+ part.getFigure().translateToAbsolute(figBounds);
+ if(contentArea.contains(figBounds)) {
+ boundsOK = true;
+ }
+ }
+ if(boundsOK) {
+ // check group can contain
+ EObject child = part.resolveSemanticElement();
+ for(EReference refToChildren : descriptor.getChildrenReferences()) {
+ if(refToChildren.getEReferenceType().isInstance(child)) {
+ groupParts.add(part);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return new ArrayList<IGraphicalEditPart>(groupParts);
+ }
+
+ // Debug purpose
+ public static void drawRect(IGraphicalEditPart editPart, Rectangle refContentArea) {
+ RoundedRectangle rectFeedback = new RoundedRectangle();
+ rectFeedback.setBounds(refContentArea);
+ rectFeedback.setCornerDimensions(new Dimension(0, 0));
+ rectFeedback.setLineWidth(2);
+ rectFeedback.setLineStyle(Graphics.LINE_DASH);
+ rectFeedback.setForegroundColor(editPart.getFigure().getForegroundColor());
+ rectFeedback.setOpaque(true);
+ rectFeedback.setFill(false);
+
+ IFigure layer = LayerManager.Helper.find(editPart).getLayer(LayerConstants.FEEDBACK_LAYER);
+ layer.add(rectFeedback);
+ }
+
+ /**
+ * Get the command to change the graphical parent of an element
+ *
+ * @param childPart
+ * the child edit part to change parent
+ * @param newParent
+ * the new graphical parent
+ * @return the command or null if no effect
+ */
+ public static Command getUpdateGraphicalParentCmd(IGraphicalEditPart childPart, IGraphicalEditPart newParent) {
+ if(childPart.getParent().equals(newParent)) {
+ return null;
+ }
+ ChangeBoundsRequest request = new ChangeBoundsRequest();
+ request.setMoveDelta(new Point(0, 0));
+ request.setSizeDelta(new Dimension(0, 0));
+ request.setEditParts(childPart);
+ Point loc = childPart.getFigure().getBounds().getLocation().getCopy();
+ childPart.getFigure().translateToAbsolute(loc);
+ request.setLocation(loc);
+ request.setType(RequestConstants.REQ_DROP);
+ org.eclipse.gef.commands.Command cmd = newParent.getCommand(request);
+ if(cmd != null && cmd.canExecute()) {
+ return new GEFtoEMFCommandWrapper(cmd);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the command to add a reference from a parent group edit part to its new child
+ *
+ * @param newParentpart
+ * the new parent edit part which contains children by reference
+ * @param newChildPart
+ * the child edit part
+ * @return the command or null
+ */
+ public static Command getAddReferenceToChildCmd(IGraphicalEditPart newParentpart, IGraphicalEditPart newChildPart) {
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(newParentpart);
+ EObject parent = newParentpart.resolveSemanticElement();
+ EObject child = newChildPart.resolveSemanticElement();
+ // get the better child reference to use
+ EReference usedReference = getBestReferenceAmongList(desc.getChildrenReferences(), child);
+ if(usedReference != null) {
+ return new AddCommand(newParentpart.getEditingDomain(), parent, usedReference, child);
+ } else {
+ // no possible child reference
+ return null;
+ }
+ }
+
+ /**
+ * Get the best reference (nearest to child's type) to a child among the list
+ *
+ * @param childrenReferences
+ * the possible children references
+ * @param child
+ * the child eobject to choose a referencefor
+ * @return the most precise child reference or null
+ */
+ public static EReference getBestReferenceAmongList(List<EReference> childrenReferences, EObject child) {
+ EReference usedReference = null;
+ for(EReference ref : childrenReferences) {
+ if(ref.getEReferenceType().isInstance(child)) {
+ if(usedReference == null || ref.getEReferenceType().getEAllSuperTypes().contains(usedReference.getEReferenceType())) {
+ // the ref feature is more precise than the previously selected one. Use it instead.
+ usedReference = ref;
+ }
+ }
+ }
+ return usedReference;
+ }
+
+ /**
+ * Get the command to remove a reference from a parent group edit part to its old child
+ *
+ * @param oldParentpart
+ * the old parent edit part which contains children by reference
+ * @param oldChildPart
+ * the child edit part
+ * @return the command or null
+ */
+ public static Command getRemoveReferenceToChildCmd(IGraphicalEditPart oldParentpart, IGraphicalEditPart oldChildPart) {
+ AbstractContainerNodeDescriptor desc = GroupContainmentRegistry.getContainerDescriptor(oldParentpart);
+ EObject parent = oldParentpart.resolveSemanticElement();
+ EObject child = oldChildPart.resolveSemanticElement();
+ CompoundCommand globalCmd = new CompoundCommand();
+ // get the better child reference to use
+ EReference usedReference = null;
+ for(EReference ref : desc.getChildrenReferences()) {
+ if(parent.eGet(ref) instanceof List<?>) {
+ if(((List<?>)parent.eGet(ref)).contains(child)) {
+ // remove the reference to the child
+ Command cmd = new RemoveCommand(oldParentpart.getEditingDomain(), parent, usedReference, child);
+ if(cmd.canExecute()) {
+ globalCmd.append(cmd);
+ }
+ }
+ }
+ }
+ if(!globalCmd.isEmpty()) {
+ return globalCmd;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the bounds of an edit part
+ *
+ * @param part
+ * edit part to find bounds
+ * @return part's bounds in absolute coordinates
+ */
+ public static Rectangle getAbsoluteBounds(IGraphicalEditPart part) {
+ // take bounds from figure
+ part.getTopGraphicEditPart().refresh();
+ Rectangle bounds = part.getFigure().getBounds().getCopy();
+
+ if(part.getNotationView() instanceof Node) {
+ // rather update with up to date model bounds
+ Node node = (Node)part.getNotationView();
+ LayoutConstraint cst = node.getLayoutConstraint();
+ if(cst instanceof Bounds) {
+ Bounds b = (Bounds)cst;
+ Point parentLoc = part.getFigure().getParent().getBounds().getLocation();
+ if(b.getX() > 0) {
+ bounds.x = b.getX() + parentLoc.x;
+ }
+ if(b.getY() > 0) {
+ bounds.y = b.getY() + parentLoc.y;
+ }
+ if(b.getHeight() != -1) {
+ bounds.height = b.getHeight();
+ }
+ if(b.getWidth() != -1) {
+ bounds.width = b.getWidth();
+ }
+ }
+ }
+
+ part.getFigure().getParent().translateToAbsolute(bounds);
+
+ return bounds;
+ }
+
+ /**
+ * This method compute the delta between to IGraphicalEditPart.
+ *
+ * @param oldParent
+ * Old IGraphicalEditPart
+ * @param newParent
+ * New IGraphicalEditPart
+ * @return Return a DDimention between the two bounds (often use to translate point or Rectangle)
+ */
+ public static Dimension computeDeltaToChangeParent(IGraphicalEditPart oldParent, IGraphicalEditPart newParent) {
+ Rectangle hostBounds = Utils.getAbsoluteBounds(oldParent);
+ Rectangle parentBounds = Utils.getAbsoluteBounds(newParent);
+ Dimension delta = hostBounds.getLocation().getDifference(parentBounds.getLocation());
+ return delta;
+ }
+
+ public static Dimension computeDeltaToChangeParent(IGraphicalEditPart oldParent, Rectangle newParent) {
+ Rectangle hostBounds = Utils.getAbsoluteBounds(oldParent);
+ Dimension delta = hostBounds.getLocation().getDifference(newParent.getLocation());
+ return delta;
+ }
+
+ /**
+ * Give the reference object which can reference the child for the parent type part
+ *
+ * @param parentType
+ * EClass of the parent OBject you want to know the EReference
+ * @param childType
+ * EClass of the child you want to test
+ * @return null if no reference is found
+ */
+ public static EReference getContainmentEReference(EClass parentType, EClass childType) {
+ List<EReference> result = new ArrayList<EReference>();
+ EReference usedReference = null;
+ for(EReference reference : parentType.getEAllContainments()) {
+ if(reference.getEReferenceType().isSuperTypeOf(childType) && !reference.isDerived()) {
+ result.add(reference);
+ }
+ }
+
+ //Select the best containment relation
+ for(EReference ref : result) {
+ if(usedReference == null || ref.getEReferenceType().getEAllSuperTypes().contains(usedReference.getEReferenceType())) {
+ // the ref feature is more precise than the previously selected one. Use it instead.
+ usedReference = ref;
+ }
+ }
+ return usedReference;
+ }
+
+ /**
+ *
+ * @param editPartRegistry
+ * Check if the object is contained in the editPartRegistery
+ * @param _child
+ * @return
+ */
+ public static boolean isContainedInRegistery(Map editPartRegistry, Object _child) {
+ if(_child instanceof IGraphicalEditPart) {
+ return editPartRegistry.containsKey(((IGraphicalEditPart)_child).getModel());
+ }
+ return false;
+
+ }
+
+ /**
+ * Test is the element is a compartment edit part that can be used to create the child
+ *
+ * @param editPartRegistry
+ * @param _child
+ * @return
+ */
+ public static boolean isAGoodCompartementEditPart(Map editPartRegistry, Object _child) {
+ return _child instanceof CompartmentEditPart && isContainedInRegistery(editPartRegistry, _child) && ((EditPart)_child) instanceof ShapeCompartmentEditPart;
+ }
+
+ /**
+ * Get the compartment editPart from a parent editPart
+ *
+ * @param editPartRegistry
+ * EditPartRegistery
+ * @param parentEditPart
+ * EditPart of the parent
+ * @return the CompartementEditPart and null if not found
+ */
+ public static EditPart getCompartementEditPartFromMainEditPart(Map editPartRegistry, EditPart parentEditPart) {
+ EditPart resultCompartmentEditPart = null;
+ //An edit part has been found
+ if(parentEditPart instanceof CompartmentEditPart) {
+ resultCompartmentEditPart = parentEditPart;
+ return resultCompartmentEditPart;
+ } else {
+ List<EditPart> potentialCompartementPart = new ArrayList<EditPart>();
+ for(Object _child : parentEditPart.getChildren()) {
+ if(isAGoodCompartementEditPart(editPartRegistry, _child)) {
+ potentialCompartementPart.add((EditPart)_child);
+ }
+ }
+ if(potentialCompartementPart.size() == 1) {
+ resultCompartmentEditPart = potentialCompartementPart.get(0);
+ return resultCompartmentEditPart;
+ } else if(potentialCompartementPart.size() == 1) {
+ //FIXME find a correct behavior if several potential CompartementPart (should normally never be the case)
+ resultCompartmentEditPart = potentialCompartementPart.get(0);
+ return resultCompartmentEditPart;
+ }
+ }
+ return resultCompartmentEditPart;
+ }
+
+
+ /**
+ * Get the child map needed for {@link ChangeModelParentCommand}
+ *
+ * @param elementType
+ * {@link EClass} of the elemnt you want to find the default model parent
+ * @param getHost
+ * Host of the editPolicy
+ * @param newIgraphicalParent
+ * {@link IGraphicalEditPart} to complete with the new {@link IGraphicalEditPart} of the defautl model parent
+ * @return
+ */
+ public static DefaultModelParent getDefaultModelParent(EClass elementType, IGraphicalEditPart getHost) {
+ IGraphicalEditPart hostParent = getHost;
+
+ while(hostParent != null) {
+ EObject hostParentElement = hostParent.resolveSemanticElement();
+ if(GroupContainmentRegistry.getDescriptorsWithContainerEClass(hostParentElement.eClass()).isEmpty()) {
+ for(EReference containmentRelation : hostParentElement.eClass().getEAllContainments()) {
+ if(containmentRelation.getEReferenceType().isSuperTypeOf(elementType)) {
+ return new DefaultModelParent(hostParent, containmentRelation);
+ }
+ }
+ }
+ hostParent = (IGraphicalEditPart)hostParent.getParent();
+ }
+ return null;
+ }
+
+ public static boolean isRequestGroupFrameworkConcerned(ChangeBoundsRequest request) {
+ for(Object editPart : request.getEditParts()) {
+ if(editPart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart iGraphicalEditPart = (IGraphicalEditPart)editPart;
+ boolean isNodeConcerned = GroupContainmentRegistry.isNodeConcerned(iGraphicalEditPart);
+ boolean isGroupConcerned = GroupContainmentRegistry.isContainerConcerned(iGraphicalEditPart);
+ if(isGroupConcerned || isNodeConcerned) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/CreateInGroupEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/CreateInGroupEditPolicy.java
new file mode 100644
index 00000000000..631ff8896f6
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/CreateInGroupEditPolicy.java
@@ -0,0 +1,214 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.edit.policies;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.UnexecutableCommand;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RefreshConnectionsRequest;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.commands.EditElementCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.diagram.common.groups.commands.utlis.CommandsUtils;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+import org.eclipse.papyrus.diagram.common.groups.utils.GroupRequestConstants;
+import org.eclipse.papyrus.diagram.common.util.DiagramEditPartsUtil;
+
+
+/**
+ * This Edit Policy applies on the compartment of a group (which hold elements by reference or containment). It enables to recover the correct model
+ * container in
+ * order to create the element at the right place in the model, before linking it to the referencing group.
+ *
+ * In order to do so, the semantic creation command, inheriting {@link EditElementCommand}, must recover the
+ * {@link GroupRequestConstants#MODEL_CONTAINER} parameter from the request to know the model container of the created element and assign it itself.
+ *
+ * @author vhemery and adaussy
+ */
+public class CreateInGroupEditPolicy extends CreationEditPolicy {
+
+ /** List of the IGraphicalEditPart of the graphical parents available */
+ private List<IGraphicalEditPart> graphicalParents;
+
+ /** List of the IGraphicalEditPart of the model parents available */
+ private List<IGraphicalEditPart> modelParents;
+
+ /**
+ * Get the command to create a group referenced child and create it in the appropriate place.
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy#getCreateElementAndViewCommand(org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest)
+ *
+ * @param request
+ * the creation request
+ * @return the creation command or null
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Command getCreateElementAndViewCommand(CreateViewAndElementRequest request) {
+ CreateElementRequestAdapter requestAdapter = request.getViewAndElementDescriptor().getCreateElementRequestAdapter();
+ CreateElementRequest createElementRequest = (CreateElementRequest)requestAdapter.getAdapter(CreateElementRequest.class);
+ //Needed to create transactionnal command
+ TransactionalEditingDomain editingDomain = ((GraphicalEditPart)getHost()).getEditingDomain();
+ //Command in creation
+ CompositeCommand handleChildren = null;
+
+
+ View view = (View)getHost().getModel();
+ EObject hostElement = ViewUtil.resolveSemanticElement(view);
+ if(hostElement == null && view.getElement() == null) {
+ hostElement = view;
+ }
+ // Returns null if host is unresolvable so that trying to create a
+ // new element in an unresolved shape will not be allowed.
+ if(hostElement == null) {
+ return null;
+ }
+ EditPart currentEditPart = getHost();
+ if(currentEditPart instanceof IGraphicalEditPart) {
+ /*
+ * Handling parents
+ */
+ DiagramEditPart diagramPart = DiagramEditPartsUtil.getDiagramEditPart(currentEditPart);
+ /*
+ * Find the edit part which can be model and graphical parent of the new element
+ */
+ graphicalParents = new ArrayList<IGraphicalEditPart>();
+ modelParents = new ArrayList<IGraphicalEditPart>();
+ Utils.createComputedListsOfParents(graphicalParents, modelParents, request, diagramPart, createElementRequest.getElementType().getEClass());
+
+ CommandsUtils.setRequestParentsParameters(request, graphicalParents, modelParents, getHost());
+
+ /*
+ * If the current host is not a model parent of the element in creation then the request is send to suitable one
+ */
+ Command relocatedCommand = CommandsUtils.sendRequestSuitableHost(request, createElementRequest, (IGraphicalEditPart)getHost(), modelParents);
+ if(relocatedCommand != null) {
+ return relocatedCommand;
+ }
+
+ /*
+ * handling sons if the creation is a group
+ */
+ Set<AbstractContainerNodeDescriptor> descriptors = GroupContainmentRegistry.getDescriptorsWithContainerEClass(createElementRequest.getElementType().getEClass());
+ handleChildren = CommandsUtils.getHandleChildrenCommand(descriptors, request, diagramPart, editingDomain, requestAdapter, modelParents, (IGraphicalEditPart)getHost());
+
+ /*
+ * Request Part Creation
+ * 1 - Create Semantic Request
+ * 2 - Create View Request
+ * 3 - Create Choice request (If there is any choice to make)
+ */
+ Command createElementCommand = getHost().getCommand(new EditCommandRequestWrapper((CreateElementRequest)requestAdapter.getAdapter(CreateElementRequest.class), request.getExtendedData()));
+
+ if(createElementCommand == null || !createElementCommand.canExecute()) {
+ return UnexecutableCommand.INSTANCE;
+ }
+ /*
+ * Create View Command
+ */
+ Command viewCommand = getCreateCommand(request);
+ /*
+ * Refresh Connection command
+ */
+ Command refreshConnectionCommand = getHost().getCommand(new RefreshConnectionsRequest(((List<?>)request.getNewObject())));
+ /*
+ * create the semantic global command
+ */
+ CompositeCommand semanticCommand = CommandsUtils.getSemanticCommand(requestAdapter, editingDomain, createElementRequest, createElementCommand, graphicalParents);
+ /*
+ * ChooseParentNotificationCommand
+ */
+ CompositeCommand choiceCommand = CommandsUtils.getChooseParentNotification(editingDomain, request, graphicalParents, modelParents, (IGraphicalEditPart)getHost());
+ /*
+ * form the compound command and return
+ */
+ CompositeCommand cc = new CompositeCommand(semanticCommand.getLabel());
+ cc.compose(semanticCommand);
+ cc.compose(new CommandProxy(viewCommand));
+ if(choiceCommand != null) {
+ cc.compose(choiceCommand);
+ }
+ if(handleChildren != null) {
+ cc.compose(handleChildren);
+ }
+ if(refreshConnectionCommand != null) {
+ cc.compose(new CommandProxy(refreshConnectionCommand));
+ }
+
+ return new ICommandProxy(cc);
+ }
+ return super.getCreateElementAndViewCommand(request);
+ }
+
+ /**
+ * Create a request in order to handle graphic creation
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy#getCreateCommand(org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest)
+ *
+ * @param request
+ * @param getHost
+ * @return
+ */
+ @Override
+ public Command getCreateCommand(CreateViewRequest request) {
+ /*
+ * Get default graphical parent
+ */
+ IGraphicalEditPart newParentPart = (IGraphicalEditPart)getHost();
+ Object graphicalParents = request.getExtendedData().get(GroupRequestConstants.GRAPHICAL_CONTAINERS);
+ if(graphicalParents instanceof List<?> && !((List<?>)graphicalParents).isEmpty()) {
+ Object parentPart = ((List<?>)graphicalParents).get(0);
+ if(parentPart instanceof IGraphicalEditPart) {
+ newParentPart = (IGraphicalEditPart)parentPart;
+ }
+ }
+ request.getExtendedData().put(CommandsUtils.GRAPHICAL_PARENT, newParentPart);
+ View parent = (View)newParentPart.getModel();
+ // construct command as in super method (except parent)
+ TransactionalEditingDomain editingDomain = ((IGraphicalEditPart)getHost()).getEditingDomain();
+ CompositeTransactionalCommand cc = new CompositeTransactionalCommand(editingDomain, DiagramUIMessages.AddCommand_Label);
+ Iterator<? extends CreateViewRequest.ViewDescriptor> descriptors = request.getViewDescriptors().iterator();
+ while(descriptors.hasNext()) {
+ CreateViewRequest.ViewDescriptor descriptor = (CreateViewRequest.ViewDescriptor)descriptors.next();
+ CreateCommand createCommand = new CreateCommand(editingDomain, descriptor, parent);
+ cc.compose(createCommand);
+ }
+ return new ICommandProxy(cc.reduce());
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/XYLayoutEditGroupPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/XYLayoutEditGroupPolicy.java
new file mode 100644
index 00000000000..ea493dd4914
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/edit/policies/XYLayoutEditGroupPolicy.java
@@ -0,0 +1,456 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.edit.policies;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gef.requests.CreateRequest;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeGraphicalParentCommand.Mode;
+import org.eclipse.papyrus.diagram.common.groups.commands.ChangeModelParentCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.SetUpReferencesCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.UpdateReferencesCommand;
+import org.eclipse.papyrus.diagram.common.groups.commands.utlis.CommandsUtils;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.DefaultModelParent;
+import org.eclipse.papyrus.diagram.common.groups.core.utils.Utils;
+import org.eclipse.papyrus.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
+import org.eclipse.papyrus.diagram.common.groups.utils.GroupRequestConstants;
+import org.eclipse.papyrus.diagram.common.util.DiagramEditPartsUtil;
+
+/**
+ * This edit policy is used to handle node positioning inside a group after creation or after a {@link ChangeBoundsRequest} You can find example of
+ * uses of this policy in {@link org.eclipse.papyrus.diagram.activity.edit.policies.CompartmentXYLayoutEditPolicy} or in
+ * {@link org.eclipse.papyrus.diagram.activity.edit.parts.ActivityPartitionActivityPartitionContentCompartmentEditPart}
+ *
+ * @author arthur daussy
+ */
+public class XYLayoutEditGroupPolicy extends XYLayoutEditPolicy {
+
+
+ /**
+ * graphical parent of the edit part after moving
+ */
+ private ArrayList<IGraphicalEditPart> graphicalParents;
+
+ /**
+ * Model parent of the edit part after moving
+ */
+ private ArrayList<IGraphicalEditPart> modelParents;
+
+ /**
+ * Graphical parent of the edit part before moving
+ */
+ private ArrayList<IGraphicalEditPart> oldGraphicalParents;
+
+ /**
+ * Model parent of the edit part before moving
+ */
+ private ArrayList<IGraphicalEditPart> oldModelParents;
+
+ /**
+ * override this method in order to take into account the difference between graphical parent and model parent.
+ * If there are different there is a delta to compute and the figure has to be translated.
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy#getConstraintFor(org.eclipse.gef.requests.CreateRequest)
+ * @param request
+ * @return
+ */
+ @Override
+ protected Object getConstraintFor(CreateRequest request) {
+ if(request.getExtendedData().containsKey(CommandsUtils.GRAPHICAL_PARENT) && request.getExtendedData().containsKey(CommandsUtils.NEW_PARENT_HOST)) {
+ IGraphicalEditPart graphicalParent = (IGraphicalEditPart)request.getExtendedData().get(CommandsUtils.GRAPHICAL_PARENT);
+ IGraphicalEditPart newHost = (IGraphicalEditPart)request.getExtendedData().get(CommandsUtils.NEW_PARENT_HOST);
+ Dimension delta = Utils.computeDeltaToChangeParent(newHost, graphicalParent);
+ Rectangle rectangle = (Rectangle)super.getConstraintFor(request);
+ rectangle.translate(delta.width, delta.height);
+ return (Object)rectangle;
+ }
+ return super.getConstraintFor(request);
+ }
+
+ /**
+ * Override the super method in order to disable the command if the command has already been created on another edit part
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy#getCommand(org.eclipse.gef.Request)
+ *
+ * @param request
+ * Global Request
+ * @return Command
+ */
+ @Override
+ public Command getCommand(Request request) {
+ if(understandsRequest(request)) {
+ return super.getCommand(request);
+ }
+ return null;
+ }
+
+ /**
+ * Return the resize command chained with the group-related commands if needed
+ *
+ * @param request
+ * the change bounds request
+ */
+ @Override
+ protected Command getResizeChildrenCommand(ChangeBoundsRequest request) {
+ Command superCommand = super.getResizeChildrenCommand(request);
+ if(superCommand != null) {
+ String label = superCommand.getLabel();
+ CompositeCommand commandWrapper = new CompositeCommand(label);
+ /*
+ * If there is several edit part affected by the request multiplex the request
+ */
+ Command multiplexor = CommandsUtils.requestEditPartMultiplexor(request, label, (IGraphicalEditPart)getHost());
+ if(multiplexor != null) {
+ return multiplexor;
+ }
+
+ String labelHandleChildren = "XYLayout : Handle children";
+ //Thanks to requestEditPartMultiplexor its sure we only have only one editPart
+ Object _movingEditPart = request.getEditParts().get(0);
+ if(_movingEditPart instanceof IGraphicalEditPart) {
+ IGraphicalEditPart movingEditPart = (IGraphicalEditPart)_movingEditPart;
+ IGraphicalEditPart movingCompartmentEditPart = (IGraphicalEditPart)Utils.getCompartementEditPartFromMainEditPart(((IGraphicalEditPart)getHost()).getViewer().getEditPartRegistry(), movingEditPart);
+ if(movingCompartmentEditPart == null) {
+ movingCompartmentEditPart = movingEditPart;
+ }
+ /*
+ * Find the moving compartment editPart
+ */
+ TransactionalEditingDomain editingDomain = ((GraphicalEditPart)getHost()).getEditingDomain();
+
+ /*
+ * Only handle element which are concerned by the framework else return the super method
+ */
+ boolean isNodeConcernedByGroupFramework = GroupContainmentRegistry.isNodeConcerned(movingCompartmentEditPart);
+ boolean isGroupConcernedByGroupFramework = GroupContainmentRegistry.isContainerConcerned(movingCompartmentEditPart);
+ if(isNodeConcernedByGroupFramework || isGroupConcernedByGroupFramework) {
+ /*
+ * Handling parents
+ */
+ DiagramEditPart diagramPart = DiagramEditPartsUtil.getDiagramEditPart(movingEditPart);
+ graphicalParents = new ArrayList<IGraphicalEditPart>();
+ modelParents = new ArrayList<IGraphicalEditPart>();
+ Utils.createComputedListsOfParents(graphicalParents, modelParents, movingEditPart, request, true);
+ oldGraphicalParents = new ArrayList<IGraphicalEditPart>();
+ oldModelParents = new ArrayList<IGraphicalEditPart>();
+ Utils.createComputedListsOfParents(oldGraphicalParents, oldModelParents, movingEditPart, request, false);
+
+
+ IGraphicalEditPart graphicalParent = CommandsUtils.setRequestParentsParameters(request, graphicalParents, modelParents, getHost());
+ /*
+ * The the original position of the element
+ */
+ setOriginalAbsolutePositionPosition(request, movingEditPart);
+ //If the system has found model parent
+ Command relocateCommand = CommandsUtils.sendRequestSuitableHost(request, (IGraphicalEditPart)getHost(), modelParents, movingEditPart);
+ if(relocateCommand != null) {
+ return relocateCommand;
+ }
+ /*
+ * Execute the change bound request
+ */
+ commandWrapper.compose(new CommandProxy(superCommand));
+ /*
+ * Update model
+ */
+ updateModel(commandWrapper, movingEditPart, editingDomain);
+ /*
+ * Update the references
+ * 1 - Set up new references
+ * 2 - Withdraw old references
+ */
+ updateMovingElementReferences(label, commandWrapper, movingEditPart, editingDomain);
+
+ /*
+ * Then change the graphical parent
+ */
+ CommandsUtils.getChangeGraphicalParentCommand(label, commandWrapper, movingEditPart, editingDomain, graphicalParent, (IGraphicalEditPart)getHost(), request);
+
+ /*
+ * If the change bounds element is a group
+ */
+ if(isGroupConcernedByGroupFramework) {
+ Command handleChildren = getHandleChildren(request, labelHandleChildren, movingEditPart, diagramPart, movingCompartmentEditPart, editingDomain);
+ if(handleChildren != null) {
+ commandWrapper.compose(new CommandProxy(handleChildren));
+ }
+ }
+ /*
+ * ChooseParentNotificationCommand
+ */
+ CompositeCommand choiceCommand = CommandsUtils.getChooseParentNotification(editingDomain, request, graphicalParents, modelParents, (IGraphicalEditPart)getHost());
+ if(choiceCommand != null) {
+ commandWrapper.compose(choiceCommand);
+ }
+
+ return new ICommandProxy(commandWrapper);
+ } else {
+ return superCommand;
+ }
+ }
+
+ }
+ return superCommand;
+ }
+
+ /**
+ * Update the references of the movingElement
+ *
+ * @param label
+ * Label of the command
+ * @param commandWrapper
+ * {@link CompositeCommand} in which all the command will be composed ( warning should be initialised before)
+ * @param labelHandleChildren
+ * @param movingEditPart
+ * @param editingDomain
+ */
+ private void updateMovingElementReferences(String label, CompositeCommand commandWrapper, IGraphicalEditPart movingEditPart, TransactionalEditingDomain editingDomain) {
+ SetUpReferencesCommand setUpReferences = new SetUpReferencesCommand(editingDomain, label + ": set up references", movingEditPart, graphicalParents);
+ if(setUpReferences != null) {
+ commandWrapper.compose(setUpReferences);
+ }
+ for(IGraphicalEditPart oldParent : oldGraphicalParents) {
+ if(!graphicalParents.contains(oldParent)) {
+ IGraphicalEditPart oldParentCompartmentEditPart = (IGraphicalEditPart)Utils.getCompartementEditPartFromMainEditPart(oldParent.getViewer().getEditPartRegistry(), oldParent);
+ AbstractContainerNodeDescriptor descriptor = GroupContainmentRegistry.getContainerDescriptor(oldParentCompartmentEditPart);
+ UpdateReferencesCommand withDrawReference = new UpdateReferencesCommand(editingDomain, label + ": withdraw old references", Collections.singletonList(movingEditPart), descriptor, oldParent, UpdateReferencesCommand.UNSET_MODE);
+ if(withDrawReference != null) {
+ commandWrapper.compose(withDrawReference);
+ }
+ }
+ }
+ }
+
+ /**
+ * This model update the model parent of the moving node
+ *
+ * @param commandWrapper
+ * Resulting command in wich the new command should be composed (should not be null)
+ * @param movingEditPart
+ * {@link IGraphicalEditPart} of the moving element
+ * @param editingDomain
+ * {@link EditingDomain}
+ */
+ private void updateModel(CompositeCommand commandWrapper, IGraphicalEditPart movingEditPart, TransactionalEditingDomain editingDomain) {
+ EditPart host = getHost();
+ //CHANGE
+ if(!movingEditPart.getParent().equals(host)) {
+ if(host != null) {
+ EditPart compartmentEditPartHost = Utils.getCompartementEditPartFromMainEditPart(movingEditPart.getViewer().getEditPartRegistry(), host);
+ if(compartmentEditPartHost instanceof IGraphicalEditPart) {
+ AbstractContainerNodeDescriptor group = GroupContainmentRegistry.getContainerDescriptor((IGraphicalEditPart)compartmentEditPartHost);
+ EReference ref = null;
+ Map<EObject, EReference> child = null;
+ EObject childEObject = movingEditPart.resolveSemanticElement();
+ if(group != null) {
+ EObject movingEObject = childEObject;
+ if(movingEObject != null) {
+ if(group.canIBeModelParentOf(movingEObject.eClass())) {
+ ref = group.getContainmentReferenceFor(movingEObject.eClass());
+ child = Collections.singletonMap(movingEObject, ref);
+ }
+ }
+ } else {
+ DefaultModelParent defaultModelContainer = Utils.getDefaultModelParent(childEObject.eClass(), (IGraphicalEditPart)getHost());
+ ref = defaultModelContainer.geteReference();
+ child = Collections.singletonMap(childEObject, defaultModelContainer.geteReference());
+ }
+ if(ref != null && child != null) {
+ ChangeModelParentCommand changeModelParent = new ChangeModelParentCommand(editingDomain, compartmentEditPartHost, child, movingEditPart);
+ if(changeModelParent != null) {
+ commandWrapper.compose(changeModelParent);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Set in the request the absolute coordinate of the moving element
+ *
+ * @param request
+ * @param movingEditPart
+ */
+ @SuppressWarnings("unchecked")
+ private void setOriginalAbsolutePositionPosition(ChangeBoundsRequest request, IGraphicalEditPart movingEditPart) {
+ //if(!request.getExtendedData().containsKey(GroupRequestConstants.CONSTRAINT_AFTER_MOVING) && movingEditPart instanceof IGraphicalEditPart) {
+ if(movingEditPart instanceof IGraphicalEditPart) {
+ Rectangle bounds = ((Rectangle)getConstraintFor(request, movingEditPart)).getCopy();
+ translateFromLayoutRelativeToAbsolute(bounds);
+ request.getExtendedData().put(GroupRequestConstants.CONSTRAINT_AFTER_MOVING, bounds);
+ }
+ }
+
+
+ /**
+ * Command to handle all children of the moving element
+ *
+ * @param request
+ * The {@link ChangeBoundsRequest}
+ * @param label
+ * A label fro the request
+ * @param movingEditPart
+ * The {@link IGraphicalEditPart} of the moving element
+ * @param diagramPart
+ * {@link IGraphicalEditPart} of the diagram
+ * @param movingCompartmentEditPart
+ * The compartment {@link IGraphicalEditPart} of the moving node
+ * @param editingDomain
+ * {@link EditingDomain}
+ * @param compartmentMovingEditPart
+ * @return the resulting command or null if nothing to do
+ */
+ private Command getHandleChildren(ChangeBoundsRequest request, String label, IGraphicalEditPart movingEditPart, DiagramEditPart diagramPart, IGraphicalEditPart movingCompartmentEditPart, TransactionalEditingDomain editingDomain) {
+
+ CompositeCommand result = new CompositeCommand(label);
+
+ if(movingCompartmentEditPart != null && GroupContainmentRegistry.isContainerConcerned(movingCompartmentEditPart)) {
+
+ CompositeCommand handleChildren = null;
+ /*
+ * handling sons if the creation is a group
+ */
+ Set<AbstractContainerNodeDescriptor> descriptors = GroupContainmentRegistry.getDescriptorsWithContainerEClass(movingEditPart.resolveSemanticElement().eClass());
+ handleChildren = CommandsUtils.getHandleChildrenCommand(descriptors, request, diagramPart, editingDomain, movingEditPart, modelParents, (IGraphicalEditPart)getHost());
+ if(handleChildren != null) {
+ result.compose(handleChildren);
+ }
+ /*
+ * Change the the graphical parent of the GroupRequestConstants.GRAPHICAL_CHILDREN) set in the getHandleChildrenCommand
+ */
+ if(request.getExtendedData().containsKey(GroupRequestConstants.GRAPHICAL_CHILDREN)) {
+ List<IGraphicalEditPart> automaticChildren = (List<IGraphicalEditPart>)request.getExtendedData().get(GroupRequestConstants.GRAPHICAL_CHILDREN);
+ for(IGraphicalEditPart child : automaticChildren) {
+ if(child instanceof IGraphicalEditPart) {
+ ChangeGraphicalParentCommand cmd = new ChangeGraphicalParentCommand(editingDomain, label, movingEditPart, child, (IGraphicalEditPart)getHost(), request);
+ if(cmd != null) {
+ cmd.setMode(Mode.MOVE_PARENT);
+ result.compose(cmd);
+ }
+ }
+ }
+ }
+ result.reduce();
+ if(!result.isEmpty()) {
+ return new ICommandProxy(result);
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Override to be able to prevent several execution of the CreateCommand
+ * The Create command will only be used if the new host parent is in the request
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#understandsRequest(org.eclipse.gef.Request)
+ *
+ * @param req
+ * Global request
+ * @return
+ */
+ @Override
+ public boolean understandsRequest(Request req) {
+ return canHandleCreateRequestOnlyIfNewParent(req, (IGraphicalEditPart)getHost());
+ }
+
+ /**
+ * Return true except if the request is a create request in which {@link CreateInGroupEditPolicy#OLD_PARENT} and
+ * {@link CommandsUtils#NEW_PARENT_HOST} are set and are different
+ *
+ * @param req
+ * The global request
+ * @param getHost
+ * The host on the edit policy
+ * @return True if can execute
+ */
+ public static boolean canHandleCreateRequestOnlyIfNewParent(Request req, IGraphicalEditPart getHost) {
+ //If there is a NEW_PARENT_HOST data then its means than the command has been asked to another edit part before
+ // If this host is the new host then it executes the create command
+ // Else do nothing
+ //Else the command will not be asked to another EditPart so I have to execute it
+ if(req.getExtendedData().containsKey(CommandsUtils.NEW_PARENT_HOST)) {
+ IGraphicalEditPart newParent = (IGraphicalEditPart)req.getExtendedData().get(CommandsUtils.NEW_PARENT_HOST);
+ if(((getHost).equals(newParent))) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get the command to response of CreateRequest request.
+ * Override in order to set the graphical children of the created element
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy#getCreateCommand(org.eclipse.gef.requests.CreateRequest)
+ *
+ * @param request
+ * @return
+ */
+ @Override
+ protected Command getCreateCommand(CreateRequest request) {
+ if(request.getExtendedData().containsKey(GroupRequestConstants.GRAPHICAL_CHILDREN)) {
+ TransactionalEditingDomain editingDomain = ((IGraphicalEditPart)getHost()).getEditingDomain();
+ Command superCreateCommand = super.getCreateCommand(request);
+ CompositeCommand compositeCreateCmd = new CompositeCommand(superCreateCommand.getLabel());
+ compositeCreateCmd.compose(new CommandProxy(superCreateCommand));
+ List<IGraphicalEditPart> automaticChildren = (List<IGraphicalEditPart>)request.getExtendedData().get(GroupRequestConstants.GRAPHICAL_CHILDREN);
+ for(IGraphicalEditPart child : automaticChildren) {
+ if(child instanceof IGraphicalEditPart) {
+ String label = superCreateCommand + ": Change child graphical parent";
+ ChangeGraphicalParentCommand cmd = new ChangeGraphicalParentCommand(editingDomain, label, request, child, (IGraphicalEditPart)getHost());
+ if(cmd != null) {
+ cmd.setMode(Mode.CREATION_CHILD);
+ compositeCreateCmd.compose(cmd);
+ }
+ }
+ }
+ return new ICommandProxy(compositeCreateCmd);
+ }
+ return super.getCreateCommand(request);
+ }
+
+
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/groupcontainment/AbstractContainerNodeDescriptor.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/groupcontainment/AbstractContainerNodeDescriptor.java
new file mode 100644
index 00000000000..eada82c041a
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/groupcontainment/AbstractContainerNodeDescriptor.java
@@ -0,0 +1,158 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.groupcontainment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * This abstract class describes the required methods to register to the org.eclipse.papyrus.diagram.common.groups.groupcontainment extension point.
+ * These methods allow to recover necessary information on the container node for a given type.
+ *
+ * @author adaussy
+ */
+
+public abstract class AbstractContainerNodeDescriptor {
+
+ /**
+ * Get the eclass of the model eobject represented by the node
+ *
+ * @return model object eclass
+ */
+ public abstract EClass getContainerEClass();
+
+ public List<EClass> getPossibleGraphicalChildren() {
+ List<EReference> refs = this.getChildrenReferences();
+ List<EClass> result = new ArrayList<EClass>(refs.size());
+ for(EReference ref : refs) {
+ result.add(ref.getEReferenceType());
+ }
+ return result;
+ }
+
+ /**
+ * Get the area in which contained children are located.
+ *
+ * @param containerPart
+ * the part containing children, and representing an element of the getContainerEClass() eclass
+ * @return the rectangle in which nodes are considered as children of this part (absolute coordinates)
+ */
+ public Rectangle getContentArea(IGraphicalEditPart containerPart) {
+ Rectangle bounds = containerPart.getContentPane().getBounds().getCopy();
+ containerPart.getContentPane().translateToAbsolute(bounds);
+ return bounds;
+ }
+
+ /**
+ * Get the list of references linking the container to children element.
+ * Note that these may not be direct containment relations in case the element is only a graphical container.
+ *
+ * @return the references to contained elements
+ */
+ public abstract List<EReference> getChildrenReferences();
+
+ /**
+ * Get the edit part which is registered to the group framework (compartment) from a view of the corresponding node.
+ *
+ * @param nodeView
+ * a view of the node, which can be either the compartment's view or the primary view of the containing node
+ * @param diagramPart
+ * the diagram edit part (used to recover parts from views)
+ * @return the compartment edit part which is registered to the group framework
+ */
+ public abstract IGraphicalEditPart getPartFromView(View nodeView, DiagramEditPart diagramPart);
+
+ /**
+ * Give you the right be a graphical parent of child.
+ *
+ * @param childType
+ * EClass of the child you want to test
+ * @return
+ */
+ public boolean canIBeGraphicalParentOf(EClass childType) {
+ for(EReference reference : this.getChildrenReferences()) {
+ if(reference.getEReferenceType().isSuperTypeOf(childType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Give you the right to be a model parent of child
+ *
+ * @param childType
+ * EClass of the child you want to test
+ * @return
+ */
+ public boolean canIBeModelParentOf(EClass childType) {
+ for(EReference reference : this.getChildrenReferences()) {
+ if(reference.getEReferenceType().isSuperTypeOf(childType) && reference.isContainment()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Give the reference object which can reference the child.
+ *
+ * @param childType
+ * EClass of the child you want to test
+ * @return null if no reference is found
+ */
+ public List<EReference> getReferenceFor(EClass childType) {
+ List<EReference> result = new ArrayList<EReference>();
+ for(EReference reference : this.getChildrenReferences()) {
+ if(reference.getEReferenceType().isSuperTypeOf(childType) && !reference.isContainment()) {
+ result.add(reference);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Give the reference object which can contain the child.
+ *
+ * @param childType
+ * EClass of the child you want to test
+ * @return null if no reference is found
+ */
+ public EReference getContainmentReferenceFor(EClass childType) {
+ EReference usedReference = null;
+ List<EReference> result = new ArrayList<EReference>();
+ for(EReference reference : this.getChildrenReferences()) {
+ if(reference.getEReferenceType().isSuperTypeOf(childType) && reference.isContainment() && !reference.isDerived()) {
+ result.add(reference);
+ }
+ }
+ //Select the best containment relation
+ for(EReference ref : result) {
+ if(usedReference == null || ref.getEReferenceType().getEAllSuperTypes().contains(usedReference.getEReferenceType())) {
+ // the ref feature is more precise than the previously selected one. Use it instead.
+ usedReference = ref;
+ }
+ }
+ return usedReference;
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityFactoryHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityFactoryHelper.java
new file mode 100644
index 00000000000..c608defd0c7
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityFactoryHelper.java
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.preferences;
+
+import org.eclipse.draw2d.Shape;
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Factory Helper used to set the opacity setting on groups ( setAlpha , listenner, preferences etc...)
+ *
+ * @author adaussy
+ *
+ */
+public class OpacityFactoryHelper {
+
+ /**
+ * Get the preference group to set the opqcity
+ *
+ * @param parent
+ * @param key
+ * @param dialogPage
+ * @param preferenceName
+ * @return
+ */
+ static public OpacityGroup getOpacityGroup(Composite parent, String key, DialogPage dialogPage, String preferenceName) {
+ return new OpacityGroup(parent, key, dialogPage, preferenceName);
+ }
+
+ /**
+ * Init the opacity preferences of a figure
+ *
+ * @param preferenceName
+ * Name of the preferences which point to the alpha preference
+ * @param store
+ * Preference Store
+ * @param figure
+ * Figure on which the alpha setting has to be made
+ */
+ static public void initOpacityPreferences(final String preferenceName, final IPreferenceStore store, final Shape figure) {
+ Integer defaultAlpha = getStoredValueOfOpacity(preferenceName, store);
+ figure.setAlpha(defaultAlpha);
+ store.addPropertyChangeListener(new IPropertyChangeListener() {
+
+ public void propertyChange(PropertyChangeEvent event) {
+ if(preferenceName.equals(event.getProperty())) {
+ if(figure != null) {
+ figure.setAlpha(store.getInt(preferenceName));
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Get the store value of the alpha setting
+ *
+ * @param preferenceName
+ * name of the preference
+ * @param store
+ * Preference store
+ * @return
+ */
+ static public Integer getStoredValueOfOpacity(String preferenceName, IPreferenceStore store) {
+ return new Integer(store.getInt(preferenceName));
+ }
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityGroup.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityGroup.java
new file mode 100644
index 00000000000..7b8336725d5
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/preferences/OpacityGroup.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:
+ * Atos Origin - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.diagram.common.groups.preferences;
+
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.preference.ScaleFieldEditor;
+import org.eclipse.papyrus.diagram.common.ui.helper.HelpComponentFactory;
+import org.eclipse.papyrus.preferences.ui.AbstractGroup;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * Group use to set the opacity of a compartment of a group
+ *
+ * @author adaussy
+ *
+ */
+public class OpacityGroup extends AbstractGroup {
+
+ /**
+ * Name of the preferance to set
+ */
+ protected String preferenceName;
+
+ public OpacityGroup(Composite parent, String key, DialogPage dialogPage, String preferenceName) {
+ super(parent, key, dialogPage);
+ this.preferenceName = preferenceName;
+ createContent(parent);
+ }
+
+ /**
+ * Creates the content.
+ *
+ * @param parent
+ * the parent
+ */
+ public void createContent(Composite parent) {
+ Group visibilityGroup = new Group(parent, SWT.SCROLL_PAGE);
+ /*
+ * TODO Refactor layout (help component at the end of the line)
+ */
+ visibilityGroup.setLayout(new GridLayout());
+ visibilityGroup.setText("Opacity of the compartment");
+
+ ScaleFieldEditor alphaEditor = new ScaleFieldEditor(preferenceName, "Opacity", visibilityGroup, 0, 255, 5, 20);
+ alphaEditor.setPage(dialogPage);
+ addFieldEditor(alphaEditor);
+ HelpComponentFactory.createHelpComponent(visibilityGroup, new FormToolkit(parent.getDisplay()), "Set to min to make the compartment totally transparent");
+ }
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSection.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSection.java
new file mode 100644
index 00000000000..6ea59510302
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSection.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:
+ * Atos Origin - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.diagram.common.groups.tabbedproperties.appearance;
+
+import org.eclipse.gmf.runtime.diagram.ui.properties.sections.AbstractNotationPropertiesSection;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Section to use in the properties view. This section enables to choose which of the possible parents graphically contains the selected node.
+ *
+ * @author vhemery
+ */
+public class ChooseGraphicalParentSection extends AbstractNotationPropertiesSection {
+
+ /** The switch image. */
+ public static Image switchImage = null;
+
+ /** Load the switch icon once */
+ static {
+ ////load images
+ // try {
+ // switchImage = new Image(Display.getDefault(), Activator.getDefault().getBundle().getResource(ICON_PATH).openStream());
+ // } catch (IOException e) {
+ // Activator.getDefault().getLog().log(new Status(Status.WARNING, Activator.PLUGIN_ID, e.getMessage(), e));
+ // }
+ }
+
+ /**
+ * Create controls to enable direction switch
+ */
+ @Override
+ public void initializeControls(Composite parent) {
+ super.initializeControls(parent);
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSectionFilter.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSectionFilter.java
new file mode 100644
index 00000000000..9eaf3730cea
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/tabbedproperties/appearance/ChooseGraphicalParentSectionFilter.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:
+ * Atos Origin - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.diagram.common.groups.tabbedproperties.appearance;
+
+import org.eclipse.jface.viewers.IFilter;
+
+/**
+ * Filter for the {@link ChooseGraphicalParentSection} section
+ *
+ * @author vhemery
+ */
+public class ChooseGraphicalParentSectionFilter implements IFilter {
+
+ /**
+ * Select the object only in case it is contained by several groups
+ *
+ * @param object
+ * object to compare against the filter
+ * @return <code>true</code> if the object is accepted by the filter.
+ */
+ public boolean select(Object object) {
+ //FIXME enable when the group property section is developped
+ return false;
+ // Class<ChooseGraphicalParentSection> cl = ChooseGraphicalParentSection.class;
+ // try {
+ // cl.newInstance();
+ // } catch (InstantiationException e) {
+ // e.printStackTrace();
+ // } catch (IllegalAccessException e) {
+ // e.printStackTrace();
+ // }
+ // if(object instanceof IGraphicalEditPart) {
+ // return GroupContainmentRegistry.isContainerConcerned((IGraphicalEditPart)object);
+ // } else {
+ // return false;
+ // }
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GraphicalAndModelElementComparator.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GraphicalAndModelElementComparator.java
new file mode 100644
index 00000000000..4a332c26499
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GraphicalAndModelElementComparator.java
@@ -0,0 +1,176 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.utils;
+
+import java.util.Comparator;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.papyrus.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
+
+/**
+ * This comparator give a way to have compare two IgraphicalEditParts by their parental link.
+ * If A is an ancestor of B in the graphical model or in the model then A<B
+ * If B is an ancestor of A in the graphical model or in the model then A<B
+ * else A=B (there is no parent link between them)
+ *
+ * @author adaussy
+ *
+ */
+public class GraphicalAndModelElementComparator implements Comparator<IGraphicalEditPart> {
+
+ /**
+ *
+ * @author adaussy
+ */
+ public static enum Mode {
+ /** Define the model comparison mode */
+ MODEL,
+ /** Define the graphical comparison mode */
+ GRAPHICAL_AND_MODEL;
+ }
+
+ /**
+ * Current mode of the comparator
+ *
+ * @see {@link GraphicalAndModelElementComparator.Mode}
+ */
+ private Mode mode;
+
+ private Map registery;
+
+
+
+ public GraphicalAndModelElementComparator(IGraphicalEditPart anypart) {
+ mode = Mode.GRAPHICAL_AND_MODEL;
+ this.registery = anypart.getViewer().getEditPartRegistry();
+ }
+
+ public GraphicalAndModelElementComparator(Mode mode, IGraphicalEditPart anypart) {
+ this.mode = mode;
+ this.registery = anypart.getViewer().getEditPartRegistry();
+ }
+
+ /**
+ * Get the current mode
+ *
+ * @return Current Mode
+ */
+ public Mode getMode() {
+ return mode;
+ }
+
+ /**
+ * Set the current mode
+ *
+ * @param mode
+ * we want to set @see {@link GraphicalAndModelElementComparator.Mode}
+ */
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Compare two IGraphicalEditPart.
+ * If o1 is an ancestor of o2 in the graphical model or in the model then o2>o1
+ * If o2 is an ancestor of o1 in the graphical model or in the model then o2<o1
+ * else o2 = o1
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ public int compare(IGraphicalEditPart o1, IGraphicalEditPart o2) {
+ if(o1.equals(o2)) {
+ return 0;
+ } else {
+ if(Mode.GRAPHICAL_AND_MODEL.equals(mode)) {
+ /*
+ * Compute the Graphic comparison
+ */
+ EditPart o1Graphic = o1;
+ EditPart o2Graphic = o2;
+ /*
+ * Look if o1 is an ancestor of o2 (graphical model)
+ */
+ EditPart graphicalParent = o2Graphic.getParent();
+ while(graphicalParent != null) {
+ if(graphicalParent.equals(o1Graphic)) {
+ return -1;
+ }
+ graphicalParent = graphicalParent.getParent();
+ }
+ /*
+ * Look if o2 is an ancestor of o1 (graphical model)
+ */
+ graphicalParent = o1Graphic.getParent();
+ while(graphicalParent != null) {
+ if(graphicalParent == o2Graphic) {
+ return 1;
+ }
+ graphicalParent = graphicalParent.getParent();
+ }
+ }
+
+ /*
+ * Compute the Model comparison
+ */
+ EObject o1model = o1.resolveSemanticElement();
+ EObject o2model = o2.resolveSemanticElement();
+ return compare(o1model, o2model);
+ }
+
+ }
+
+ public int compare(EObject o1model, EObject o2model) {
+ /*
+ * Look if o1 is an ancestor on the model of o2
+ */
+ EObject modelParent = o2model.eContainer();
+ /*
+ * Find the edit part of the modelParent
+ */
+ IGraphicalEditPart modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
+ while(modelParent != null || GroupContainmentRegistry.isContainerConcerned(modelParentEditPart)) {
+ if(modelParent == o1model) {
+ return -1;
+ }
+ modelParent = modelParent.eContainer();
+ modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
+ }
+ /*
+ * Look if o2 is an ancestor on the model of o2
+ */
+ modelParent = o2model.eContainer();
+ /*
+ * Find the edit part of the modelParent
+ */
+ modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
+ while(modelParent != null) {
+ if(modelParent == o2model || GroupContainmentRegistry.isContainerConcerned(modelParentEditPart)) {
+ return -1;
+ }
+ modelParent = modelParent.eContainer();
+ modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
+ }
+ return 0;
+ }
+
+
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GroupRequestConstants.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GroupRequestConstants.java
new file mode 100644
index 00000000000..1695c7e8dba
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common.groups/src/org/eclipse/papyrus/diagram/common/groups/utils/GroupRequestConstants.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * 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.diagram.common.groups.utils;
+
+/**
+ * This class contains constants used by requests concerned by groups
+ *
+ * @author vhemery
+ */
+public class GroupRequestConstants {
+
+ /**
+ * The constant to recover the list of all available elements which can contain (from a model point of view) the created element.
+ * Used as Parameter key in semantic requests.
+ */
+ public static final String MODEL_CONTAINERS = "GROUP_MODEL_CONTAINERS";
+
+ /**
+ * The constant to recover the list of all available elements which can graphically contain the created element.
+ * Used as key for graphical request extended data
+ */
+ public static final String GRAPHICAL_CONTAINERS = "GROUP_GRAPHICAL_CONTAINERS";
+
+ /**
+ * Used to notify the user that the notification to choose the parent failed
+ */
+ public static final String CHOOSE_PARENT_ERROR_NOTIFICATION = "The notification failed to run because no list of avaiable parent was set up";
+
+ /**
+ * The constant to recover the list of all graphical graphical children after group creation
+ */
+ public static final String GRAPHICAL_CHILDREN = "ALL_AUTOMATIC_GRAPHICAL_CHILDREN";
+
+ /**
+ * Constant set in the extended data of a request. It used to know if the edit part handling the request should launch a refrech to all group it
+ * intersect
+ */
+ public static final String SEND_UPDATE_REFERENCE_TO_CHILDREN = "HAS_TO_SEND_UPDATE_REFERENCE_TO_CHILDREN";
+
+ /**
+ * Initial constrain of the element targeted by a request
+ */
+ public static final String CONSTRAINT_AFTER_MOVING = "CONSTRAINT_AFTER_MOVING";
+}

Back to the top