Bug 543847 - Add capability to select several PictogramElements from a
selection of PictogramElement

Should work for
* Selection of single PE
* Add further PE to selection (press shift while clicking)
* Create new PE

Change-Id: I08da909cdc527fc333fcbc05a880e0f9f1ae7ff8
diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/editor/GraphitiScrollingGraphicalViewer.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/editor/GraphitiScrollingGraphicalViewer.java
index 5810883..6cc7e0d 100644
--- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/editor/GraphitiScrollingGraphicalViewer.java
+++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/internal/editor/GraphitiScrollingGraphicalViewer.java
@@ -1,7 +1,7 @@
 /*******************************************************************************
  * <copyright>
  *
- * Copyright (c) 2005, 2010 SAP AG.
+ * Copyright (c) 2005, 2019 SAP AG.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@
  *    Bug 336488 - DiagramEditor API
  *    pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface
  *    fvelasco - Bug 323356 - Mouse-wheel support for scrolling and zooming
+ *    Hubert Guerard, mwenz - Bug 543847 - Add capability to select several PictogramElement from a selection of PictogramElement
  *
  * </copyright>
  *
@@ -26,6 +27,7 @@
 import org.eclipse.gef.MouseWheelZoomHandler;
 import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
 import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
 import org.eclipse.graphiti.tb.IToolBehaviorProvider;
 import org.eclipse.graphiti.ui.editor.DiagramBehavior;
 import org.eclipse.graphiti.ui.internal.util.gef.MouseWheelHorizontalScrollHandler;
@@ -47,16 +49,21 @@
 	@Override
 	public void select(EditPart editpart) {
 		IToolBehaviorProvider tbp = getDiagramBehavior().getDiagramTypeProvider().getCurrentToolBehaviorProvider();
-		boolean connectionPossible = tbp.isConnectionSelectionEnabled();
+		boolean connectionSelectionEnabled = tbp.isConnectionSelectionEnabled();
 
-		if (connectionPossible) {
-			super.select(editpart);
-			return;
-		} else {
-			Object model = editpart.getModel();
-			if (!(model instanceof Connection)) {
-				super.select(editpart);
-				return;
+		Object model = editpart.getModel();
+		if (connectionSelectionEnabled || !(model instanceof Connection)) {
+			if (model != null && model instanceof PictogramElement) {
+				deselectAll();
+				PictogramElement[] newSelection = tbp.getSelections((PictogramElement) model);
+				if (newSelection != null) {
+					for (PictogramElement selectionElement : newSelection) {
+						EditPart editPart = (EditPart) getEditPartRegistry().get(selectionElement);
+						if (editPart != null) {
+							super.appendSelection(editPart);
+						}
+					}
+				}
 			}
 		}
 	}
@@ -64,116 +71,72 @@
 	@Override
 	public void setSelection(ISelection newSelection) {
 		IToolBehaviorProvider tbp = getDiagramBehavior().getDiagramTypeProvider().getCurrentToolBehaviorProvider();
-		boolean multiPossible = tbp.isMultiSelectionEnabled();
-		boolean connectionPossible = tbp.isConnectionSelectionEnabled();
+		boolean connectionSelectionPossible = tbp.isConnectionSelectionEnabled();
 
-		// default case
-		if (multiPossible && connectionPossible) {
-			super.setSelection(newSelection);
-			return;
-		}
-
-		// multi possible but no connection
-		if (multiPossible && !connectionPossible) {
-			boolean change = false;
-			List<Object> l = new ArrayList<Object>();
-			if (newSelection instanceof IStructuredSelection) {
-				IStructuredSelection strSel = (IStructuredSelection) newSelection;
-				for (int i = 0; i < strSel.toArray().length; i++) {
-					Object o = strSel.toArray()[i];
-					if (o instanceof EditPart) {
-						EditPart editpart = (EditPart) o;
-						if (editpart.getModel() instanceof Connection) {
-							change = true;
-							continue;
-						}
-					}
-					l.add(o);
-				}
-			}
-			if (change) {
-				newSelection = new StructuredSelection(l);
-			}
-			super.setSelection(newSelection);
-			return;
-		}
-
-		// connection possible but no multi select
-		if (!multiPossible && connectionPossible) {
-			if (newSelection instanceof IStructuredSelection) {
-				IStructuredSelection strSel = (IStructuredSelection) newSelection;
-				for (int i = 0; i < strSel.toArray().length; i++) {
-					Object o = strSel.toArray()[i];
-					if (o instanceof EditPart) {
-						EditPart ep = (EditPart) o;
-						select(ep);
-						return;
-					}
-				}
-				deselectAll();
-			}
-			return;
-		}
-
-		// no multi and no connection selection
-		if (!multiPossible && !connectionPossible) {
-			if (newSelection instanceof IStructuredSelection) {
-				IStructuredSelection strSel = (IStructuredSelection) newSelection;
-				for (int i = 0; i < strSel.toArray().length; i++) {
-					Object o = strSel.toArray()[i];
-					if (o instanceof EditPart) {
-						EditPart ep = (EditPart) o;
-						if (!(ep.getModel() instanceof Connection)) {
-							select(ep);
-							return;
+		boolean change = false;
+		List<Object> selectionList = new ArrayList<Object>();
+		if (newSelection instanceof IStructuredSelection) {
+			IStructuredSelection strSel = (IStructuredSelection) newSelection;
+			for (int i = 0; i < strSel.toArray().length; i++) {
+				Object object = strSel.toArray()[i];
+				if (object instanceof EditPart) {
+					EditPart editPart = (EditPart) object;
+					Object modelObject = editPart.getModel();
+					if (modelObject instanceof PictogramElement) {
+						if (connectionSelectionPossible || !(modelObject instanceof Connection)) {
+							PictogramElement[] models = tbp.getSelections((PictogramElement) modelObject);
+							if (models != null) {
+								for (PictogramElement model : models) {
+									EditPart modelEditPart = (EditPart) getEditPartRegistry().get(model);
+									if (modelEditPart != null) {
+										if (!selectionList.contains(modelObject)) {
+											selectionList.add(modelEditPart);
+											change = true;
+										}
+									}
+								}
+							} else {
+								if (tbp.isMultiSelectionEnabled() || selectionList.isEmpty()) {
+									selectionList.add(editPart);
+									change = true;
+								}
+							}
 						}
 					}
 				}
+			}
+			if (!tbp.isMultiSelectionEnabled()) {
 				deselectAll();
 			}
-			return;
 		}
+		if (change) {
+			newSelection = new StructuredSelection(selectionList);
+		}
+		super.setSelection(newSelection);
 	}
 
 	@Override
 	public void appendSelection(EditPart editpart) {
 		IToolBehaviorProvider tbp = getDiagramBehavior().getDiagramTypeProvider().getCurrentToolBehaviorProvider();
-		boolean multiPossible = tbp.isMultiSelectionEnabled();
-		boolean connectionPossible = tbp.isConnectionSelectionEnabled();
+		Object model = editpart.getModel();
 
-		// default case
-		if (multiPossible && connectionPossible) {
-			super.appendSelection(editpart);
+		if (!tbp.isConnectionSelectionEnabled() && model instanceof Connection) {
 			return;
 		}
 
-		// multi possible but no connection
-		if (multiPossible && !connectionPossible) {
-			Object model = editpart.getModel();
-			if (model instanceof Connection) {
-				return;
-			} else {
-				super.appendSelection(editpart);
-				return;
-			}
-		}
-
-		// connection possible but no multi select
-		if (!multiPossible && connectionPossible) {
+		if (!tbp.isMultiSelectionEnabled()) {
 			deselectAll();
-			super.appendSelection(editpart);
-			return;
 		}
 
-		// no multi and no connection selection
-		if (!multiPossible && !connectionPossible) {
-			Object model = editpart.getModel();
-			if (model instanceof Connection) {
-				return;
-			} else {
-				deselectAll();
-				super.appendSelection(editpart);
-				return;
+		if (model instanceof PictogramElement) {
+			PictogramElement[] pes = tbp.getSelections((PictogramElement) model);
+			if (pes != null) {
+				for (PictogramElement pe : pes) {
+					EditPart editPart = (EditPart) getEditPartRegistry().get(pe);
+					if (editPart != null) {
+						super.appendSelection(editPart);
+					}
+				}
 			}
 		}
 	}
diff --git a/plugins/org.eclipse.graphiti/.settings/.api_filters b/plugins/org.eclipse.graphiti/.settings/.api_filters
index a11f614..056165f 100644
--- a/plugins/org.eclipse.graphiti/.settings/.api_filters
+++ b/plugins/org.eclipse.graphiti/.settings/.api_filters
@@ -48,4 +48,12 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="src/org/eclipse/graphiti/tb/DefaultToolBehaviorProvider.java" type="org.eclipse.graphiti.tb.DefaultToolBehaviorProvider">
+        <filter id="576725006">
+            <message_arguments>
+                <message_argument value="IToolBehaviorProvider"/>
+                <message_argument value="DefaultToolBehaviorProvider"/>
+            </message_arguments>
+        </filter>
+    </resource>
 </component>
diff --git a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/DefaultToolBehaviorProvider.java b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/DefaultToolBehaviorProvider.java
index adf585e..a4e46e9 100644
--- a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/DefaultToolBehaviorProvider.java
+++ b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/DefaultToolBehaviorProvider.java
@@ -1,7 +1,7 @@
 /*******************************************************************************
  * <copyright>
  *
- * Copyright (c) 2005, 2017 SAP AG.
+ * Copyright (c) 2005, 2019 SAP AG.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -18,6 +18,7 @@
  *    mwenz - Bug 421754 - Absolute position of active Shape nested in inactive ContainerShape is calculated incorrectly
  *    mwenz - Bug 428068 - Automatically unselect a tool entry in palette like 'connection creation' after execution
  *    mwenz - Bug 520392 - Hard coded error message when entering an empty string in direct editing
+ *    Hubert Guerard, mwenz - Bug 543847 - Add capability to select several PictogramElement from a selection of PictogramElement 
  * </copyright>
  *
  *******************************************************************************/
@@ -138,6 +139,15 @@
 	}
 
 	/**
+	 * @since 0.16
+	 */
+	@Override
+	public PictogramElement[] getSelections(PictogramElement selection) {
+		PictogramElement[] selections = { selection };
+		return selections;
+	}
+
+	/**
 	 * @since 0.10
 	 */
 	public IConnectionSelectionInfo getSelectionInfoForConnection(Connection connection) {
diff --git a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/IToolBehaviorProvider.java b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/IToolBehaviorProvider.java
index c274f2b..6f6b1d4 100644
--- a/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/IToolBehaviorProvider.java
+++ b/plugins/org.eclipse.graphiti/src/org/eclipse/graphiti/tb/IToolBehaviorProvider.java
@@ -1,7 +1,7 @@
 /*******************************************************************************
  * <copyright>
  *
- * Copyright (c) 2005, 2017 SAP AG.
+ * Copyright (c) 2005, 2019 SAP AG.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -17,6 +17,7 @@
  *    mwenz - Bug 428068 - Automatically unselect a tool entry in palette like 'connection creation' after execution
  *    mwenz - Bug 434458 - Connections don't support Color decorators
  *    mwenz - Bug 520392 - Hard coded error message when entering an empty string in direct editing
+ *    Hubert Guerard, mwenz - Bug 543847 - Add capability to select several PictogramElement from a selection of PictogramElement
  * </copyright>
  *
  *******************************************************************************/
@@ -176,6 +177,11 @@
 	PictogramElement getSelection(PictogramElement originalPe, PictogramElement[] oldSelection);
 
 	/**
+	 * @since 0.16
+	 */
+	PictogramElement[] getSelections(PictogramElement selection);
+
+	/**
 	 * Override this method if you want to change the default scrolling behavior
 	 * of the diagram. The default is DiagramScrollingBehavior.GEF_DEFAULT: the
 	 * empty diagram comes up without scroll bars. The scroll bars start to