[111892] gmf_head crevells 070518 First milestone of group/ungroup support (painting issues when grouping shapes with border items)
diff --git a/org.eclipse.gmf.examples.runtime.diagram.geoshapes/plugin.xml b/org.eclipse.gmf.examples.runtime.diagram.geoshapes/plugin.xml
index d761182..d07a4c9 100644
--- a/org.eclipse.gmf.examples.runtime.diagram.geoshapes/plugin.xml
+++ b/org.eclipse.gmf.examples.runtime.diagram.geoshapes/plugin.xml
@@ -117,9 +117,35 @@
<partAction menubarPath="/file/print" id="printPreviewAction">
</partAction>
</partContribution>
- </contributionItemProvider>
+ </contributionItemProvider>
</extension>
-
+
+ <extension id="GeoshapesExampleGroupContributionItemProvider" name="GeoshapesExampleGroupContributionItemProvider" point="org.eclipse.gmf.runtime.common.ui.services.action.contributionItemProviders">
+ <contributionItemProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContributionItemProvider">
+ <Priority name="Low">
+ </Priority>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria
+ objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart"
+ objectCount="2+">
+ <method
+ name="getDiagramEditDomain().getEditorPart().getEditorSite().getId()"
+ value="GeoshapeEditor"/>
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="groupAction">
+ </popupAction>
+ </popupContribution>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart">
+ <method
+ name="getDiagramEditDomain().getEditorPart().getEditorSite().getId()"
+ value="GeoshapeEditor"/>
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="ungroupAction">
+ </popupAction>
+ </popupContribution>
+ </contributionItemProvider>
+ </extension>
<extension point="org.eclipse.emf.ecore.extension_parser">
<parser type="geo" class="org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory">
diff --git a/org.eclipse.gmf.examples.runtime.diagram.logic/plugin.xml b/org.eclipse.gmf.examples.runtime.diagram.logic/plugin.xml
index fb4de01..d949a6b 100644
--- a/org.eclipse.gmf.examples.runtime.diagram.logic/plugin.xml
+++ b/org.eclipse.gmf.examples.runtime.diagram.logic/plugin.xml
@@ -242,6 +242,33 @@
</contributionItemProvider>
</extension>
+ <extension id="LogicExampleGroupContributionItemProvider" name="LogicExampleGroupContributionItemProvider" point="org.eclipse.gmf.runtime.common.ui.services.action.contributionItemProviders">
+ <contributionItemProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContributionItemProvider">
+ <Priority name="Low">
+ </Priority>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria
+ objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart"
+ objectCount="2+">
+ <method
+ name="getDiagramEditDomain().getEditorPart().getEditorSite().getId()"
+ value="LogicEditor"/>
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="groupAction">
+ </popupAction>
+ </popupContribution>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart">
+ <method
+ name="getDiagramEditDomain().getEditorPart().getEditorSite().getId()"
+ value="LogicEditor"/>
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="ungroupAction">
+ </popupAction>
+ </popupContribution>
+ </contributionItemProvider>
+ </extension>
+
<extension id="LogicModelingAssistantProvider" name="%logic.provider.modelingassistant" point="org.eclipse.gmf.runtime.emf.ui.modelingAssistantProviders">
<modelingAssistantProvider class="org.eclipse.gmf.examples.runtime.diagram.logic.internal.providers.LogicModelingAssistantProvider">
<Priority name="Low"/>
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/GroupCommand.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/GroupCommand.java
new file mode 100644
index 0000000..84a16bf
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/GroupCommand.java
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+package org.eclipse.gmf.runtime.diagram.core.commands;
+
+import java.util.Iterator;
+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.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.core.internal.l10n.DiagramCoreMessages;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.notation.Bounds;
+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.NotationFactory;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * This command groups node views (i.e. shapes) together. It creates a new group
+ * view and reparents the nodes passed in to be children of the group. The
+ * nodes' locations are also changed to be relative to the location of the
+ * group.
+ *
+ * @author crevells, mmostafa
+ */
+public class GroupCommand
+ extends AbstractTransactionalCommand {
+
+ private List nodes;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param nodes
+ * A list of nodes (i.e. shape views) that are to be grouped. The
+ * nodes must all have the same parent.
+ */
+ public GroupCommand(TransactionalEditingDomain editingDomain, List nodes) {
+ this(editingDomain, nodes, null);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param nodes
+ * A list of nodes (i.e. shape views) that are to be grouped. The
+ * nodes must all have the same parent.
+ * @param options
+ * for the transaction in which this command executes, or
+ * <code>null</code> for the default options
+ */
+ public GroupCommand(TransactionalEditingDomain editingDomain, List nodes,
+ Map options) {
+ super(editingDomain, DiagramCoreMessages.GroupCommand_Label, options,
+ getWorkspaceFiles(nodes));
+ this.nodes = nodes;
+ }
+
+ /**
+ * Creates the new group, reparents the nodes, and sets the locations of the
+ * group and nodes as appropriate.\
+ */
+ protected CommandResult doExecuteWithResult(
+ IProgressMonitor progressMonitor, IAdaptable info)
+ throws ExecutionException {
+
+ Node group = NotationFactory.eINSTANCE.createNode();
+ group.setType(ViewType.GROUP);
+ group.setElement(null);
+
+ View parentView = (View) ((View) getNodes().get(0)).eContainer();
+
+ for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
+ Object view = iter.next();
+ if (view instanceof Node) {
+ ((View) ((Node) view).eContainer()).removeChild((View) view);
+ }
+ }
+
+ parentView.getPersistedChildren().add(group);
+
+ int x = 0;
+ int y = 0;
+
+ boolean first = true;
+ for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
+ Object view = iter.next();
+ if (view instanceof Node) {
+ LayoutConstraint layoutConstraint = ((Node) view)
+ .getLayoutConstraint();
+ if (layoutConstraint instanceof Location) {
+ Location location = (Location) layoutConstraint;
+ if (first) {
+ x = location.getX();
+ y = location.getY();
+ first = false;
+ } else {
+ if (x > location.getX())
+ x = location.getX();
+ if (y > location.getY())
+ y = location.getY();
+ }
+ }
+ group.insertChild((View) view);
+ }
+ }
+
+ Bounds groupBounds = NotationFactory.eINSTANCE.createBounds();
+ groupBounds.setX(x);
+ groupBounds.setY(y);
+ groupBounds.setWidth(-1);
+ groupBounds.setHeight(-1);
+ group.setLayoutConstraint(groupBounds);
+
+ translateChildrenLocations(x, y);
+ return CommandResult.newOKCommandResult(group);
+ }
+
+ /**
+ * Translate the location of the children to be relative to the group's
+ * location.
+ *
+ * @param x
+ * @param y
+ */
+ protected void translateChildrenLocations(int x, int y) {
+ if (x == 0 && y == 0)
+ return;
+ for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
+ Object view = iter.next();
+ if (view instanceof Node) {
+ LayoutConstraint layoutConstraint = ((Node) view)
+ .getLayoutConstraint();
+ if (layoutConstraint instanceof Location) {
+ Location location = (Location) layoutConstraint;
+ location.setX(location.getX() - x);
+ location.setY(location.getY() - y);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the list of nodes to be grouped.
+ *
+ * @return the list of nodes to be grouped
+ */
+ protected List getNodes() {
+ return nodes;
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/UngroupCommand.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/UngroupCommand.java
new file mode 100644
index 0000000..8d94bd1
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/commands/UngroupCommand.java
@@ -0,0 +1,122 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+package org.eclipse.gmf.runtime.diagram.core.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.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.core.internal.l10n.DiagramCoreMessages;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand;
+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;
+
+/**
+ * This command ungroups a group view. It reparents the children of the group so
+ * that their parent is the group's parent and it deletes the group view. The
+ * children's locations are also changed to be relative to the location of their
+ * new parent.
+ *
+ * @author crevells
+ */
+public class UngroupCommand
+ extends AbstractTransactionalCommand {
+
+ private Node group;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param groupView
+ * the group view to ungroup
+ */
+ public UngroupCommand(TransactionalEditingDomain editingDomain,
+ Node groupView) {
+ this(editingDomain, groupView, null);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param groupView
+ * the group view to ungroup
+ * @param options
+ * for the transaction in which this command executes, or
+ * <code>null</code> for the default options
+ */
+ public UngroupCommand(TransactionalEditingDomain editingDomain,
+ Node group, Map options) {
+ super(editingDomain, DiagramCoreMessages.UngroupCommand_Label, options,
+ getWorkspaceFiles(group));
+ this.group = group;
+ }
+
+ protected CommandResult doExecuteWithResult(
+ IProgressMonitor progressMonitor, IAdaptable info)
+ throws ExecutionException {
+
+ translateChildrenLocations();
+
+ View parentView = (View) getGroup().eContainer();
+ if (parentView != null) {
+ parentView.getPersistedChildren().addAll(
+ getGroup().getPersistedChildren());
+ }
+
+ DestroyElementCommand.destroy(getGroup());
+
+ return CommandResult.newOKCommandResult();
+ }
+
+ /**
+ * Translate the location of the children to no longer be relative to the
+ * group's location.
+ */
+ protected void translateChildrenLocations() {
+ Location groupLocation = (Location) getGroup().getLayoutConstraint();
+
+ for (Iterator iter = getGroup().getChildren().iterator(); iter
+ .hasNext();) {
+ Object child = iter.next();
+ if (child instanceof Node) {
+ LayoutConstraint layoutConstraint = ((Node) child)
+ .getLayoutConstraint();
+ if (layoutConstraint instanceof Location) {
+ Location location = (Location) layoutConstraint;
+ location.setX(location.getX() + groupLocation.getX());
+ location.setY(location.getY() + groupLocation.getY());
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Returns the group to be ungrouped.
+ *
+ * @return the group to be ungrouped.
+ */
+ protected Node getGroup() {
+ return group;
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/edithelpers/NotationViewDependentsAdvice.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/edithelpers/NotationViewDependentsAdvice.java
index ead45a0..ebf2836 100644
--- a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/edithelpers/NotationViewDependentsAdvice.java
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/edithelpers/NotationViewDependentsAdvice.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -24,6 +24,9 @@
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.core.commands.UngroupCommand;
+import org.eclipse.gmf.runtime.diagram.core.internal.commands.AdjustGroupLocationCommand;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
import org.eclipse.gmf.runtime.emf.core.util.CrossReferenceAdapter;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest;
@@ -37,105 +40,128 @@
* Edit helper advice for the {@link DestroyDependentsRequest} that destroys
* notations views under the following circumstances:
* <ul>
- * <li>element being destroyed is the view's semantic referent</li>
- * <li>element being destroyed is a Node or Edge to which an Edge is connected</li>
+ * <li>element being destroyed is the view's semantic referent</li>
+ * <li>element being destroyed is a Node or Edge to which an Edge is connected</li>
* </ul>
- *
+ *
* @author Christian W. Damus (cdamus)
*/
public class NotationViewDependentsAdvice extends AbstractEditHelperAdvice {
- public ICommand getBeforeEditCommand(IEditCommandRequest request) {
- if (request instanceof DestroyDependentsRequest) {
- return getBeforeDestroyDependentsCommand((DestroyDependentsRequest) request);
- }
- return null;
- }
-
- public ICommand getAfterEditCommand(IEditCommandRequest request) {
- return null;
- }
-
- protected ICommand getBeforeDestroyDependentsCommand(
- DestroyDependentsRequest request) {
-
- EObject destructee = request.getElementToDestroy();
+ public ICommand getBeforeEditCommand(IEditCommandRequest request) {
+ if (request instanceof DestroyDependentsRequest) {
+ return getBeforeDestroyDependentsCommand((DestroyDependentsRequest) request);
+ }
+ return null;
+ }
+
+ public ICommand getAfterEditCommand(IEditCommandRequest request) {
+ return null;
+ }
+
+ protected ICommand getBeforeDestroyDependentsCommand(
+ DestroyDependentsRequest request) {
+
+ EObject destructee = request.getElementToDestroy();
CrossReferenceAdapter crossReferenceAdapter = getCrossReferenceAdapter(request, destructee);
- ICommand result = getDestroyDependentsCommand(destructee, request,
- NotationPackage.Literals.VIEW__ELEMENT, crossReferenceAdapter);
- // handle the node entries for views
- if (destructee instanceof View) {
+ ICommand result = getDestroyDependentsCommand(destructee, request,
+ NotationPackage.Literals.VIEW__ELEMENT, crossReferenceAdapter);
+ // handle the node entries for views
+ if (destructee instanceof View) {
result = CompositeCommand.compose(result, getDestroyDependentsCommand(destructee, request,
NotationPackage.Literals.NODE_ENTRY__KEY, crossReferenceAdapter));
- // handle the edges connected to nodes or other edges
- if (destructee instanceof Node || destructee instanceof Edge) {
- View view = (View) destructee;
+ // handle the edges connected to nodes or other edges
+ if (destructee instanceof Node || destructee instanceof Edge) {
+ View view = (View) destructee;
- if (view.eIsSet(NotationPackage.Literals.VIEW__SOURCE_EDGES)) {
- result = CompositeCommand.compose(result, request
- .getDestroyDependentsCommand(view.getSourceEdges()));
- }
- if (view.eIsSet(NotationPackage.Literals.VIEW__TARGET_EDGES)) {
- result = CompositeCommand.compose(result, request
- .getDestroyDependentsCommand(view.getTargetEdges()));
- }
- }
- }
- return result;
- }
-
- private CrossReferenceAdapter getCrossReferenceAdapter(
- DestroyDependentsRequest request, EObject destructee) {
-
- CrossReferenceAdapter crossReferenceAdapter = null;
- Map cacheMaps = (Map) request.getParameter("Cache_Maps");//$NON-NLS-1$ RequestCacheEntries.Cache_Maps
- if (cacheMaps != null) {
- crossReferenceAdapter = (CrossReferenceAdapter) cacheMaps
- .get("CrossRefAdapter");//$NON-NLS-1$ RequestCacheEntries.CrossRefAdapter
- }
+ if (view.eIsSet(NotationPackage.Literals.VIEW__SOURCE_EDGES)) {
+ result = CompositeCommand.compose(result, request
+ .getDestroyDependentsCommand(view.getSourceEdges()));
+ }
+ if (view.eIsSet(NotationPackage.Literals.VIEW__TARGET_EDGES)) {
+ result = CompositeCommand.compose(result, request
+ .getDestroyDependentsCommand(view.getTargetEdges()));
+ }
+ }
+ }
- if (crossReferenceAdapter == null) {
- crossReferenceAdapter = CrossReferenceAdapter
- .getExistingCrossReferenceAdapter(destructee);
- if (crossReferenceAdapter == null) {
- TransactionalEditingDomain domain = TransactionUtil
- .getEditingDomain(destructee);
- if (domain != null) {
- crossReferenceAdapter = CrossReferenceAdapter
- .getCrossReferenceAdapter(domain.getResourceSet());
- }
- }
- }
- return crossReferenceAdapter;
- }
-
-
- private ICommand getDestroyDependentsCommand(EObject destructee,
+ // handle deletion of groups
+ if (destructee instanceof Node) {
+ EObject parent = ((Node) destructee).eContainer();
+ if (parent instanceof Node
+ && ViewType.GROUP.equals(((Node) parent).getType())) {
+ if (((Node) parent).getChildren().size() == 2) {
+ // There will only be one child of the group left after this
+ // child is destroyed, so remove the group as well.
+ result = CompositeCommand.compose(result,
+ new UngroupCommand(request.getEditingDomain(),
+ (Node) parent));
+ } else {
+ // The remaining group's location may require changing after
+ // the deletion.
+ result = CompositeCommand.compose(result,
+ new AdjustGroupLocationCommand(request
+ .getEditingDomain(), (Node) parent));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private CrossReferenceAdapter getCrossReferenceAdapter(
+ DestroyDependentsRequest request, EObject destructee) {
+
+ CrossReferenceAdapter crossReferenceAdapter = null;
+ Map cacheMaps = (Map) request.getParameter("Cache_Maps");//$NON-NLS-1$ RequestCacheEntries.Cache_Maps
+ if (cacheMaps != null) {
+ crossReferenceAdapter = (CrossReferenceAdapter) cacheMaps
+ .get("CrossRefAdapter");//$NON-NLS-1$ RequestCacheEntries.CrossRefAdapter
+ }
+
+ if (crossReferenceAdapter == null) {
+ crossReferenceAdapter = CrossReferenceAdapter
+ .getExistingCrossReferenceAdapter(destructee);
+ if (crossReferenceAdapter == null) {
+ TransactionalEditingDomain domain = TransactionUtil
+ .getEditingDomain(destructee);
+ if (domain != null) {
+ crossReferenceAdapter = CrossReferenceAdapter
+ .getCrossReferenceAdapter(domain.getResourceSet());
+ }
+ }
+ }
+ return crossReferenceAdapter;
+ }
+
+ private ICommand getDestroyDependentsCommand(EObject destructee,
DestroyDependentsRequest request, EReference eRef, CrossReferenceAdapter crossReferenceAdapter) {
-
- if (crossReferenceAdapter != null) {
- Collection revRefs = crossReferenceAdapter
- .getNonNavigableInverseReferences(destructee);
- if (revRefs.isEmpty() == false) {
- Set set = null;
- Iterator it = revRefs.iterator();
- while (it.hasNext()) {
- Setting setting = (Setting) it.next();
- if (setting.getEStructuralFeature() == eRef) {
- if (set == null) {
- set = new HashSet();
- }
- set.add(setting.getEObject());
- }
- }
- if (set != null) {
- return request.getDestroyDependentsCommand(set);
- }
- }
- }
+ if (crossReferenceAdapter != null) {
+ Collection revRefs = crossReferenceAdapter
+ .getNonNavigableInverseReferences(destructee);
+ if (revRefs.isEmpty() == false) {
+ Set set = null;
+ Iterator it = revRefs.iterator();
+ while (it.hasNext()) {
+ Setting setting = (Setting) it.next();
+ if (setting.getEStructuralFeature() == eRef) {
+ if (set == null) {
+ set = new HashSet();
+ }
+ set.add(setting.getEObject());
+ }
+ }
- return null;
- }
+ if (set != null) {
+ return request.getDestroyDependentsCommand(set);
+ }
+ }
+ }
+
+ return null;
+ }
+
+
}
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/commands/AdjustGroupLocationCommand.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/commands/AdjustGroupLocationCommand.java
new file mode 100644
index 0000000..1d09b9f
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/commands/AdjustGroupLocationCommand.java
@@ -0,0 +1,133 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.core.internal.commands;
+
+import java.util.Iterator;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.diagram.core.internal.l10n.DiagramCoreMessages;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+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.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * This command will relocate the group so that the group's location reflects
+ * the location of the top-most and left-most shape. The locations of all the
+ * children will also be updated so that they are relative to the new location
+ * of the group. It can be used after a shape in the group has been moved,
+ * resized, or deleted.
+ *
+ * @author crevells
+ */
+public class AdjustGroupLocationCommand
+ extends AbstractTransactionalCommand {
+
+ private View groupView;
+
+ /**
+ * Creates a new instance.
+ */
+ public AdjustGroupLocationCommand(TransactionalEditingDomain domain,
+ View groupView) {
+ super(domain, DiagramCoreMessages.AdjustLocation_Label,
+ getWorkspaceFiles(groupView));
+ this.groupView = groupView;
+ }
+
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
+ IAdaptable info)
+ throws ExecutionException {
+
+ int minChildX = Integer.MAX_VALUE;
+ int minChildY = Integer.MAX_VALUE;
+
+ for (Iterator iterator = groupView.getChildren().iterator(); iterator
+ .hasNext();) {
+ View childView = (View) iterator.next();
+
+ if (childView instanceof Node) {
+ LayoutConstraint layoutConstraint = ((Node) childView)
+ .getLayoutConstraint();
+ if (layoutConstraint instanceof Location) {
+ Location childLocation = (Location) layoutConstraint;
+
+ if (childLocation.getX() < minChildX) {
+ minChildX = childLocation.getX();
+ }
+ if (childLocation.getY() < minChildY) {
+ minChildY = childLocation.getY();
+ }
+ }
+ }
+ }
+
+ if (minChildX != 0) {
+
+ // The group's x location must change and consequently all the
+ // children x locations as they are relative to the group's
+ // location.
+
+ Integer x = (Integer) ViewUtil.getStructuralFeatureValue(groupView,
+ NotationPackage.eINSTANCE.getLocation_X());
+ ViewUtil.setStructuralFeatureValue(groupView,
+ NotationPackage.eINSTANCE.getLocation_X(), new Integer(x
+ .intValue()
+ + minChildX));
+
+ for (Iterator iterator = groupView.getChildren().iterator(); iterator
+ .hasNext();) {
+ View childView = (View) iterator.next();
+ x = (Integer) ViewUtil.getStructuralFeatureValue(childView,
+ NotationPackage.eINSTANCE.getLocation_X());
+ ViewUtil.setStructuralFeatureValue(childView,
+ NotationPackage.eINSTANCE.getLocation_X(), new Integer(x
+ .intValue()
+ - minChildX));
+ }
+ }
+
+ if (minChildY != 0) {
+
+ // The group's y location must change and consequently all the
+ // children y locations as they are relative to the group's
+ // location.
+
+ Integer y = (Integer) ViewUtil.getStructuralFeatureValue(groupView,
+ NotationPackage.eINSTANCE.getLocation_Y());
+ ViewUtil.setStructuralFeatureValue(groupView,
+ NotationPackage.eINSTANCE.getLocation_Y(), new Integer(y
+ .intValue()
+ + minChildY));
+
+ for (Iterator iterator = groupView.getChildren().iterator(); iterator
+ .hasNext();) {
+ View childView = (View) iterator.next();
+ y = (Integer) ViewUtil.getStructuralFeatureValue(childView,
+ NotationPackage.eINSTANCE.getLocation_Y());
+ ViewUtil.setStructuralFeatureValue(childView,
+ NotationPackage.eINSTANCE.getLocation_Y(), new Integer(y
+ .intValue()
+ - minChildY));
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.java
index da80559..feaff66 100644
--- a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.java
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.java
@@ -37,6 +37,7 @@
public static String GroupCommand_Label;
public static String UngroupCommand_Label;
+ public static String AdjustLocation_Label;
static {
NLS.initializeMessages(BUNDLE_NAME, DiagramCoreMessages.class);
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.properties b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.properties
index 53c9e24..1c936d2 100644
--- a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.properties
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/internal/l10n/DiagramCoreMessages.properties
@@ -24,8 +24,9 @@
SendBackwardCommand_Label=Send Backward
SendToBackCommand_Label=Send To Back
-GroupCommand_Label = Group Shapes
-UngroupCommand_Label = Ungroup Shapes
+GroupCommand_Label = Group
+UngroupCommand_Label = Ungroup
+AdjustLocation_Label = Adjust Location
# ===============================================================================
# Diagram Internal - Translation Instruction : do not translate this section
diff --git a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/util/ViewType.java b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/util/ViewType.java
index d9fc012..a0f42ba 100644
--- a/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/util/ViewType.java
+++ b/org.eclipse.gmf.runtime.diagram.core/src/org/eclipse/gmf/runtime/diagram/core/util/ViewType.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -39,5 +39,10 @@
* the diagram link semantic hint
*/
public static String DIAGRAM_LINK = "DiagramLink"; //$NON-NLS-1$
-
+
+ /**
+ * the group semantic hint
+ */
+ public static String GROUP = "Group"; //$NON-NLS-1$
+
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/group.gif b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/group.gif
new file mode 100644
index 0000000..8f6a925
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/group.gif
Binary files differ
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/ungroup.gif b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/ungroup.gif
new file mode 100644
index 0000000..7373b3a
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/dlcl16/ungroup.gif
Binary files differ
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/group.gif b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/group.gif
new file mode 100644
index 0000000..43547d5
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/group.gif
Binary files differ
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/ungroup.gif b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/ungroup.gif
new file mode 100644
index 0000000..7d184af
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/icons/elcl16/ungroup.gif
Binary files differ
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ArrangeAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ArrangeAction.java
index b3d5d0d..1c7faac 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ArrangeAction.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ArrangeAction.java
@@ -34,6 +34,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.IEditableEditPart;
@@ -50,310 +51,322 @@
*/
public class ArrangeAction extends DiagramAction {
- private boolean selectionOnly;
+ private boolean selectionOnly;
- /**
- * @param workbenchPage
- */
- protected ArrangeAction(
- IWorkbenchPage workbenchPage,
- boolean selectionOnly) {
- super(workbenchPage);
- this.selectionOnly = selectionOnly;
- }
+ /**
+ * @param workbenchPage
+ */
+ protected ArrangeAction(
+ IWorkbenchPage workbenchPage,
+ boolean selectionOnly) {
+ super(workbenchPage);
+ this.selectionOnly = selectionOnly;
+ }
- /* (non-Javadoc)
- * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createTargetRequest()
- */
- protected Request createTargetRequest() {
- return new ArrangeRequest(getId());
- }
+ /* (non-Javadoc)
+ * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ return new ArrangeRequest(getId());
+ }
- /* (non-Javadoc)
- * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#updateTargetRequest()
- */
- protected void updateTargetRequest() {
- ArrangeRequest request = (ArrangeRequest) getTargetRequest();
- request.setPartsToArrange(getOperationSet());
- }
+ /* (non-Javadoc)
+ * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ ArrangeRequest request = (ArrangeRequest) getTargetRequest();
+ request.setPartsToArrange(getOperationSet());
+ }
- private boolean isArrangeAll() {
- return !selectionOnly;
- }
+ private boolean isArrangeAll() {
+ return !selectionOnly;
+ }
- protected Command getCommand() {
- CompoundCommand arrangeCC = new CompoundCommand(getLabel());
- if (isArrangeAll()) {
- List elements = getOperationSet();
- for (Iterator iter = elements.iterator(); iter.hasNext();) {
- EditPart element = (EditPart) iter.next();
- Command cmd = element.getCommand(getTargetRequest());
- if (cmd != null)
- arrangeCC.add(cmd);
- }
- } else if (getOperationSet().size() >= 2) {
- EditPart parent = getSelectionParent(getOperationSet());
- if (parent != null) {
- Command cmd = parent.getCommand(getTargetRequest());
- if (cmd != null)
- arrangeCC.add(cmd);
- }
- }
- return arrangeCC;
- }
+ protected Command getCommand() {
+ CompoundCommand arrangeCC = new CompoundCommand(getLabel());
+ if (isArrangeAll()) {
+ List elements = getOperationSet();
+ for (Iterator iter = elements.iterator(); iter.hasNext();) {
+ EditPart element = (EditPart) iter.next();
+ Command cmd = element.getCommand(getTargetRequest());
+ if (cmd != null)
+ arrangeCC.add(cmd);
+ }
+ } else if (getOperationSet().size() >= 2) {
+ EditPart parent = getSelectionParent(getOperationSet());
+ if (parent != null) {
+ Command cmd = parent.getCommand(getTargetRequest());
+ if (cmd != null)
+ arrangeCC.add(cmd);
+ }
+ }
+ return arrangeCC;
+ }
- /**
- * Action is enabled if arrange all. If arrange selection, action is enabled
- * if the operation set's parent has XYLayout and there is atleast 2
- * siblings to arrange
- *
- * @see org.eclipse.gef.ui.actions.EditorPartAction#calculateEnabled()
- */
- protected boolean calculateEnabled() {
-
- List operationSet = getOperationSet();
-
- //arrange all, always enable
- if( isArrangeAll() && !operationSet.isEmpty()){
- return true;
- }
+ /**
+ * Action is enabled if arrange all. If arrange selection, action is enabled
+ * if the operation set's parent has XYLayout and there is atleast 2
+ * siblings to arrange
+ *
+ * @see org.eclipse.gef.ui.actions.EditorPartAction#calculateEnabled()
+ */
+ protected boolean calculateEnabled() {
+
+ List operationSet = getOperationSet();
+
+ //arrange all, always enable
+ if( isArrangeAll() && !operationSet.isEmpty()){
+ return true;
+ }
- EditPart parentEP = getSelectionParent(operationSet);
-
- // bugzilla 156733: disable this action if the parent or selected edit parts are not editable
- if ((parentEP instanceof IEditableEditPart)
- && !((IEditableEditPart) parentEP)
- .isEditModeEnabled()) {
- return false;
- }
-
- for (Iterator i = operationSet.iterator(); i.hasNext();) {
- Object next = i.next();
- if ((next instanceof IEditableEditPart)
- && !((IEditableEditPart) next)
- .isEditModeEnabled()) {
- return false;
- }
- }
-
- //arrange selection
- if (operationSet.size() >= 2) {
- if (parentEP instanceof GraphicalEditPart) {
- GraphicalEditPart parent = (GraphicalEditPart)parentEP;
- if ((parent != null) &&(parent.getContentPane().getLayoutManager() instanceof XYLayout))
- return true;
- }
- }
- return false;
- }
+ EditPart parentEP = getSelectionParent(operationSet);
+
+ // bugzilla 156733: disable this action if the parent or selected edit parts are not editable
+ if ((parentEP instanceof IEditableEditPart)
+ && !((IEditableEditPart) parentEP)
+ .isEditModeEnabled()) {
+ return false;
+ }
+
+ for (Iterator i = operationSet.iterator(); i.hasNext();) {
+ Object next = i.next();
+ if ((next instanceof IEditableEditPart)
+ && !((IEditableEditPart) next)
+ .isEditModeEnabled()) {
+ return false;
+ }
+ }
+
+ //arrange selection
+ if (operationSet.size() >= 2) {
+ if (parentEP instanceof GraphicalEditPart) {
+ GraphicalEditPart parent = (GraphicalEditPart)parentEP;
+ if ((parent != null) &&(parent.getContentPane().getLayoutManager() instanceof XYLayout))
+ return true;
+ }
+ } else if (operationSet.size() == 1
+ && operationSet.get(0) instanceof GroupEditPart) {
+ return true;
+ }
+ return false;
+ }
- /*
- * The operation set is the shapes, connections or both on the diagrm edit part
- * (non-Javadoc)
- * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createOperationSet()
- */
- protected List createOperationSet() {
- List selection = getSelectedObjects();
-
- if( isArrangeAll() ) {
- if( !selection.isEmpty()){
- return getElementsToArrange(selection);
- }
- if( getDiagramEditPart() != null )
- return createOperationSet(getDiagramEditPart().getChildren());
+ /*
+ * The operation set is the shapes, connections or both on the diagrm edit part
+ * (non-Javadoc)
+ * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createOperationSet()
+ */
+ protected List createOperationSet() {
+ List selection = getSelectedObjects();
+
+ if( isArrangeAll() ) {
+ if( !selection.isEmpty()){
+ return getElementsToArrange(selection);
+ }
+ if( getDiagramEditPart() != null )
+ return createOperationSet(getDiagramEditPart().getChildren());
- return Collections.EMPTY_LIST;
- }
+ return Collections.EMPTY_LIST;
+ }
- if (selection.isEmpty() ||
- !(selection.get(0) instanceof IGraphicalEditPart))
- return Collections.EMPTY_LIST;
+ if (selection.isEmpty() ||
+ !(selection.get(0) instanceof IGraphicalEditPart))
+ return Collections.EMPTY_LIST;
- selection = ToolUtilities.getSelectionWithoutDependants(selection);
- return createOperationSet(selection);
- }
+ selection = ToolUtilities.getSelectionWithoutDependants(selection);
+ return createOperationSet(selection);
+ }
- /**
- * getSelectionParent
- * Utility to return the logical parent of the selection list
- *
- * @param editparts List to parse for a common parent.
- * @return EditPart that is the parent or null if a common parent doesn't exist.
- */
- private EditPart getSelectionParent(List editparts) {
- ListIterator li = editparts.listIterator();
- while (li.hasNext()) {
- Object obj = li.next();
- if (!(obj instanceof ConnectionEditPart) && obj instanceof EditPart) {
- return ((EditPart)obj).getParent();
- }
- }
-
- return null;
- }
-
- private List createOperationSet(List editparts) {
- if (editparts == null || editparts.isEmpty())
- return Collections.EMPTY_LIST;
- EditPart parent = getSelectionParent(editparts);
- if (parent == null)
- return Collections.EMPTY_LIST;
-
- for (int i = 1; i < editparts.size(); i++) {
- EditPart part = (EditPart) editparts.get(i);
- if (part instanceof ConnectionEditPart){
- continue;
- }
- if (part.getParent() != parent)
- return Collections.EMPTY_LIST;
- }
- return editparts;
- }
+ /**
+ * getSelectionParent
+ * Utility to return the logical parent of the selection list
+ *
+ * @param editparts List to parse for a common parent.
+ * @return EditPart that is the parent or null if a common parent doesn't exist.
+ */
+ private EditPart getSelectionParent(List editparts) {
+ ListIterator li = editparts.listIterator();
+ while (li.hasNext()) {
+ Object obj = li.next();
+ if (!(obj instanceof ConnectionEditPart) && obj instanceof EditPart) {
+ return ((EditPart)obj).getParent();
+ }
+ }
+
+ return null;
+ }
+
+ private List createOperationSet(List editparts) {
+ if (editparts == null || editparts.isEmpty())
+ return Collections.EMPTY_LIST;
+
+ EditPart parent;
+ if (editparts.size() == 1 && editparts.get(0) instanceof GroupEditPart) {
+ GroupEditPart groupEP = (GroupEditPart) editparts.get(0);
+ parent = groupEP;
+ editparts = groupEP.getChildren();
+ } else {
+ parent = getSelectionParent(editparts);
+ }
+
+ if (parent == null)
+ return Collections.EMPTY_LIST;
+
+ for (int i = 1; i < editparts.size(); i++) {
+ EditPart part = (EditPart) editparts.get(i);
+ if (part instanceof ConnectionEditPart){
+ continue;
+ }
+ if (part.getParent() != parent)
+ return Collections.EMPTY_LIST;
+ }
+ return editparts;
+ }
- /* (non-Javadoc)
- * @see org.eclipse.gmf.runtime.common.ui.action.AbstractActionHandler#isSelectionListener()
- */
- protected boolean isSelectionListener() {
- return true;
- }
+ /* (non-Javadoc)
+ * @see org.eclipse.gmf.runtime.common.ui.action.AbstractActionHandler#isSelectionListener()
+ */
+ protected boolean isSelectionListener() {
+ return true;
+ }
- /**
- * Creates the Arrange All action
- * @param workbenchPage
- */
- public static ArrangeAction createArrangeAllAction(IWorkbenchPage workbenchPage) {
- ArrangeAction action = new ArrangeAction(workbenchPage,false);
- action.setId(ActionIds.ACTION_ARRANGE_ALL);
- action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionLabelText);
- action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionToolTipText);
-
- action
- .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
- action
- .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED);
- action
- .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
- return action;
- }
-
- /**
- * Creates the Arrange All action for the toolbar menu
- * @param workbenchPage
- */
- public static ArrangeAction createToolbarArrangeAllAction(IWorkbenchPage workbenchPage) {
- ArrangeAction action = new ArrangeAction(workbenchPage, false);
- action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_ALL);
- action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionLabelText);
- action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionToolTipText);
-
- action
- .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
- action
- .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED);
- action
- .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
- return action;
- }
+ /**
+ * Creates the Arrange All action
+ * @param workbenchPage
+ */
+ public static ArrangeAction createArrangeAllAction(IWorkbenchPage workbenchPage) {
+ ArrangeAction action = new ArrangeAction(workbenchPage,false);
+ action.setId(ActionIds.ACTION_ARRANGE_ALL);
+ action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionLabelText);
+ action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionToolTipText);
+
+ action
+ .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
+ action
+ .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED);
+ action
+ .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
+ return action;
+ }
+
+ /**
+ * Creates the Arrange All action for the toolbar menu
+ * @param workbenchPage
+ */
+ public static ArrangeAction createToolbarArrangeAllAction(IWorkbenchPage workbenchPage) {
+ ArrangeAction action = new ArrangeAction(workbenchPage, false);
+ action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_ALL);
+ action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionLabelText);
+ action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionToolTipText);
+
+ action
+ .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
+ action
+ .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED);
+ action
+ .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL);
+ return action;
+ }
- /**
- * Creates the Arrange Selection Only action
- * @param workbenchPage
- */
- public static ArrangeAction createArrangeSelectionAction(IWorkbenchPage workbenchPage) {
- ArrangeAction action = new ArrangeAction(workbenchPage, true);
- action.setId(ActionIds.ACTION_ARRANGE_SELECTION);
- action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionLabelText);
- action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionToolTipText);
-
- action
- .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
- action
- .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED);
- action
- .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
- return action;
- }
-
- /**
- * Creates the Arrange Selection Only action for the toolbar menu
- * @param workbenchPage
- */
- public static ArrangeAction createToolbarArrangeSelectionAction(IWorkbenchPage workbenchPage) {
- ArrangeAction action = new ArrangeAction(workbenchPage, true);
- action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION);
- action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionLabelText);
- action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionToolTipText);
-
- action
- .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
- action
- .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED);
- action
- .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
- return action;
- }
-
- protected void doRun(IProgressMonitor progressMonitor) {
- IPreferenceStore preferenceStore = (IPreferenceStore) getDiagramEditPart().getDiagramPreferencesHint().getPreferenceStore();
- boolean animatedLayout = preferenceStore.getBoolean(
- IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT);
-
- if (animatedLayout)
- Animation.markBegin();
-
- super.doRun(progressMonitor);
-
- if (animatedLayout) {
- int durationInc = 800;
- int factor = 10;
- int size = 0;
-
- List operationSet = getOperationSet();
- if (isArrangeAll()){
- for (Iterator iter = operationSet.iterator(); iter.hasNext();) {
- IGraphicalEditPart element = (IGraphicalEditPart) iter.next();
- size += element.getFigure().getChildren().size();
- }
- }
- else if (operationSet != null && !operationSet.isEmpty()) {
- IGraphicalEditPart container = (IGraphicalEditPart)getSelectionParent(operationSet);
- size += container.getFigure().getChildren().size();
- }
-
- int totalDuration = Math.min(durationInc * factor / 2, Math.max(durationInc, (size /
- factor) * durationInc));
-
- Animation.run(totalDuration);
- }
- }
-
- /**
- * @param selection
- * @return
- */
- private List getElementsToArrange(List selection) {
- Set parentsSet = new HashSet();
- for (Iterator iter = selection.iterator(); iter.hasNext();) {
- Object element = iter.next();
- if (element instanceof ShapeCompartmentEditPart || element instanceof DiagramEditPart){
- parentsSet.add(element);
- } else if (element instanceof EditPart){
- EditPart gEditPart =
- (EditPart)element;
- EditPart parentEditPart = gEditPart.getParent();
- if (parentEditPart instanceof ShapeCompartmentEditPart ||
- parentEditPart instanceof DiagramEditPart){
- if (!parentsSet.contains(parentEditPart))
- parentsSet.add(parentEditPart);
- }
- }
- }
- if (parentsSet.isEmpty())
- return Collections.EMPTY_LIST;
- List elements = new ArrayList();
- elements.addAll(parentsSet);
- return elements;
- }
+ /**
+ * Creates the Arrange Selection Only action
+ * @param workbenchPage
+ */
+ public static ArrangeAction createArrangeSelectionAction(IWorkbenchPage workbenchPage) {
+ ArrangeAction action = new ArrangeAction(workbenchPage, true);
+ action.setId(ActionIds.ACTION_ARRANGE_SELECTION);
+ action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionLabelText);
+ action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionToolTipText);
+
+ action
+ .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
+ action
+ .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED);
+ action
+ .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
+ return action;
+ }
+
+ /**
+ * Creates the Arrange Selection Only action for the toolbar menu
+ * @param workbenchPage
+ */
+ public static ArrangeAction createToolbarArrangeSelectionAction(IWorkbenchPage workbenchPage) {
+ ArrangeAction action = new ArrangeAction(workbenchPage, true);
+ action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION);
+ action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionLabelText);
+ action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionToolTipText);
+
+ action
+ .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
+ action
+ .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED);
+ action
+ .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED);
+ return action;
+ }
+
+ protected void doRun(IProgressMonitor progressMonitor) {
+ IPreferenceStore preferenceStore = (IPreferenceStore) getDiagramEditPart().getDiagramPreferencesHint().getPreferenceStore();
+ boolean animatedLayout = preferenceStore.getBoolean(
+ IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT);
+
+ if (animatedLayout)
+ Animation.markBegin();
+
+ super.doRun(progressMonitor);
+
+ if (animatedLayout) {
+ int durationInc = 800;
+ int factor = 10;
+ int size = 0;
+
+ List operationSet = getOperationSet();
+ if (isArrangeAll()){
+ for (Iterator iter = operationSet.iterator(); iter.hasNext();) {
+ IGraphicalEditPart element = (IGraphicalEditPart) iter.next();
+ size += element.getFigure().getChildren().size();
+ }
+ }
+ else if (operationSet != null && !operationSet.isEmpty()) {
+ IGraphicalEditPart container = (IGraphicalEditPart)getSelectionParent(operationSet);
+ size += container.getFigure().getChildren().size();
+ }
+
+ int totalDuration = Math.min(durationInc * factor / 2, Math.max(durationInc, (size /
+ factor) * durationInc));
+
+ Animation.run(totalDuration);
+ }
+ }
+
+ /**
+ * @param selection
+ * @return
+ */
+ private List getElementsToArrange(List selection) {
+ Set parentsSet = new HashSet();
+ for (Iterator iter = selection.iterator(); iter.hasNext();) {
+ Object element = iter.next();
+ if (element instanceof ShapeCompartmentEditPart || element instanceof DiagramEditPart){
+ parentsSet.add(element);
+ } else if (element instanceof EditPart){
+ EditPart gEditPart =
+ (EditPart)element;
+ EditPart parentEditPart = gEditPart.getParent();
+ if (parentEditPart instanceof ShapeCompartmentEditPart ||
+ parentEditPart instanceof DiagramEditPart){
+ if (!parentsSet.contains(parentEditPart))
+ parentsSet.add(parentEditPart);
+ }
+ }
+ }
+ if (parentsSet.isEmpty())
+ return Collections.EMPTY_LIST;
+ List elements = new ArrayList();
+ elements.addAll(parentsSet);
+ return elements;
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ColorPropertyContributionItem.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ColorPropertyContributionItem.java
index 91a74fe..e263a37 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ColorPropertyContributionItem.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/ColorPropertyContributionItem.java
@@ -22,6 +22,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
@@ -658,5 +659,18 @@
disabledBasicImageData);
}
+
+ protected List getTargetEditParts(EditPart editpart) {
+ if (editpart instanceof GroupEditPart) {
+ List list = new ArrayList();
+ for (Iterator iter = ((GroupEditPart) editpart)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ list.addAll(getTargetEditParts((EditPart) iter.next()));
+ }
+ return list;
+ } else {
+ return super.getTargetEditParts(editpart);
+ }
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DeleteFromDiagramAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DeleteFromDiagramAction.java
index fc5d69f..1b40ecb 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DeleteFromDiagramAction.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DeleteFromDiagramAction.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -27,6 +27,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
@@ -227,6 +228,9 @@
*/
private boolean isCanonical(IGraphicalEditPart gep) {
EditPart parent = gep.getParent();
+ while (parent instanceof GroupEditPart) {
+ parent = parent.getParent();
+ }
if (parent instanceof IGraphicalEditPart) {
CanonicalEditPolicy cep = (CanonicalEditPolicy)parent.getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
if ( cep != null ) {
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DuplicateActionDelegate.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DuplicateActionDelegate.java
index 5f2036e..ef8ee3b 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DuplicateActionDelegate.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/DuplicateActionDelegate.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -32,6 +32,7 @@
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.common.ui.action.AbstractActionDelegate;
import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
@@ -170,6 +171,12 @@
List eps = new ArrayList();
for (Iterator i = selection.iterator(); i.hasNext();) {
Object selectedItem = i.next();
+
+ // Disable duplicate on groups for now. See bugzilla 182972.
+ if (selectedItem instanceof GroupEditPart) {
+ return null;
+ }
+
if (selectedItem instanceof IGraphicalEditPart) {
eps.add(selectedItem);
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontDialogAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontDialogAction.java
index 278dc41..f528117 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontDialogAction.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontDialogAction.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,11 +11,17 @@
package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.actions.PropertyChangeAction;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.diagram.ui.requests.ChangePropertyValueRequest;
@@ -89,4 +95,17 @@
}
}
+ protected List getTargetEditParts(EditPart editpart) {
+ if (editpart instanceof GroupEditPart) {
+ List targetedEPs = new ArrayList();
+ for (Iterator iter = ((GroupEditPart) editpart)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ EditPart childEP = (EditPart) iter.next();
+ targetedEPs.addAll(getTargetEditParts(childEP));
+ }
+ return targetedEPs;
+ } else {
+ return super.getTargetEditParts(editpart);
+ }
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontNameContributionItem.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontNameContributionItem.java
index 1842a47..f2f849d 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontNameContributionItem.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontNameContributionItem.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,8 +11,14 @@
package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.diagram.ui.internal.util.FontHelper;
import org.eclipse.gmf.runtime.diagram.ui.internal.util.IUIConstants;
@@ -107,4 +113,17 @@
protected boolean isOperationHistoryListener() {
return true;
}
+
+ protected List getTargetEditParts(EditPart editpart) {
+ if (editpart instanceof GroupEditPart) {
+ List list = new ArrayList();
+ for (Iterator iter = ((GroupEditPart) editpart)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ list.addAll(getTargetEditParts((EditPart) iter.next()));
+ }
+ return list;
+ } else {
+ return super.getTargetEditParts(editpart);
+ }
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontSizeContributionItem.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontSizeContributionItem.java
index dae3737..dfd8e68 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontSizeContributionItem.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontSizeContributionItem.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,8 +11,14 @@
package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.diagram.ui.internal.util.FontHelper;
import org.eclipse.gmf.runtime.diagram.ui.internal.util.IUIConstants;
@@ -105,5 +111,17 @@
protected boolean isOperationHistoryListener() {
return true;
}
-
+
+ protected List getTargetEditParts(EditPart editpart) {
+ if (editpart instanceof GroupEditPart) {
+ List list = new ArrayList();
+ for (Iterator iter = ((GroupEditPart) editpart)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ list.addAll(getTargetEditParts((EditPart) iter.next()));
+ }
+ return list;
+ } else {
+ return super.getTargetEditParts(editpart);
+ }
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontStyleAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontStyleAction.java
index c432b4c..decc412 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontStyleAction.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/FontStyleAction.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2004 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,10 +11,16 @@
package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.actions.BooleanPropertyAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.l10n.DiagramUIPluginImages;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.ui.IWorkbenchPage;
@@ -76,5 +82,18 @@
action.setDisabledImageDescriptor(DiagramUIPluginImages.DESC_ITALIC_DISABLED);
return action;
}
-
+
+ protected List getTargetEditParts(EditPart editpart) {
+ if (editpart instanceof GroupEditPart) {
+ List targetedEPs = new ArrayList();
+ for (Iterator iter = ((GroupEditPart) editpart)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ EditPart childEP = (EditPart) iter.next();
+ targetedEPs.addAll(getTargetEditParts(childEP));
+ }
+ return targetedEPs;
+ } else {
+ return super.getTargetEditParts(editpart);
+ }
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/GroupAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/GroupAction.java
new file mode 100644
index 0000000..4bc090d
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/GroupAction.java
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.UnexecutableCommand;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gef.tools.ToolUtilities;
+import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
+import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * An action to group shapes together.
+ *
+ * @author mmostafa, crevells
+ */
+public class GroupAction
+ extends DiagramAction {
+
+ /**
+ * Creates a new instance.
+ *
+ * @param workbenchPage
+ */
+ public GroupAction(IWorkbenchPage workbenchPage) {
+ super(workbenchPage);
+ setId(ActionIds.ACTION_GROUP);
+ setText(DiagramUIActionsMessages.GroupAction_Group_ActionLabelText);
+ setToolTipText(DiagramUIActionsMessages.GroupAction_Group_ActionToolTipText);
+ setImageDescriptor(DiagramUIActionsPluginImages.DESC_GROUP);
+ setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_GROUP_DISABLED);
+ setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_GROUP);
+ }
+
+ protected Request createTargetRequest() {
+ return new GroupRequest(getId());
+ }
+
+ protected void updateTargetRequest() {
+ GroupRequest request = (GroupRequest) getTargetRequest();
+ request.setEditParts(getOperationSet());
+ }
+
+ protected Command getCommand() {
+ if (getOperationSet().size() > 1) {
+ EditPart parent = ((EditPart) getOperationSet().get(0)).getParent();
+ return parent.getCommand(getTargetRequest());
+ }
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ protected List createOperationSet() {
+ List selection = getSelectedObjects();
+ if (selection.size() <= 1
+ || !(selection.get(0) instanceof IGraphicalEditPart))
+ return Collections.EMPTY_LIST;
+
+ return ToolUtilities.getSelectionWithoutDependants(selection);
+ }
+
+ protected boolean isSelectionListener() {
+ return true;
+ }
+
+ protected void doRun(IProgressMonitor progressMonitor) {
+
+ super.doRun(progressMonitor);
+
+ Object model = ((EditPart) ((GroupRequest) getTargetRequest())
+ .getEditParts().get(0)).getModel();
+ if (model instanceof View) {
+ Object groupView = ((View) model).eContainer();
+ Object groupEP = getDiagramGraphicalViewer().getEditPartRegistry()
+ .get(groupView);
+ if (groupEP != null) {
+ getDiagramGraphicalViewer().setSelection(
+ new StructuredSelection(groupEP));
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/SelectAllAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/SelectAllAction.java
index aff669f..c48ec67 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/SelectAllAction.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/SelectAllAction.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -28,6 +28,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
@@ -134,7 +135,12 @@
else {
if (editpart.isSelectable())
retval.add(editpart);
- getSelectableChildrenNodes(editpart, retval);
+
+ // Do not dig into groups -- just select the group, but not the
+ // shapes inside.
+ if (!(editpart instanceof GroupEditPart)) {
+ getSelectableChildrenNodes(editpart, retval);
+ }
}
}
}
@@ -179,7 +185,11 @@
Set connnectableEditParts = new HashSet(editparts);
ListIterator li = editparts.listIterator();
while (li.hasNext()) {
- getBorderItemEditParts((EditPart)li.next(), connnectableEditParts);
+ EditPart ep = (EditPart)li.next();
+ getBorderItemEditParts(ep, connnectableEditParts);
+ if (ep instanceof GroupEditPart) {
+ connnectableEditParts.addAll(((GroupEditPart)ep).getFlattenedChildren());
+ }
}
if (diagramEditPart != null) {
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/UngroupAction.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/UngroupAction.java
new file mode 100644
index 0000000..8c9bd38
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/UngroupAction.java
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.ui.actions.internal;
+
+import org.eclipse.gef.Request;
+import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
+import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * An action to ungroup a group of shapes.
+ *
+ * @author crevells
+ */
+public class UngroupAction
+ extends DiagramAction {
+
+ /**
+ * Creates a new instance.
+ *
+ * @param workbenchPage
+ */
+ public UngroupAction(IWorkbenchPage workbenchPage) {
+ super(workbenchPage);
+ setId(ActionIds.ACTION_UNGROUP);
+ setText(DiagramUIActionsMessages.GroupAction_Ungroup_ActionLabelText);
+ setToolTipText(DiagramUIActionsMessages.GroupAction_Ungroup_ActionToolTipText);
+ setImageDescriptor(DiagramUIActionsPluginImages.DESC_UNGROUP);
+ setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_UNGROUP_DISABLED);
+ setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_UNGROUP);
+ }
+
+ protected Request createTargetRequest() {
+ return new Request(getId());
+ }
+
+ protected boolean isSelectionListener() {
+ return true;
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/l10n/DiagramUIActionsPluginImages.java b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/l10n/DiagramUIActionsPluginImages.java
index 193f681..d1d22f1 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/l10n/DiagramUIActionsPluginImages.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.actions/src/org/eclipse/gmf/runtime/diagram/ui/actions/internal/l10n/DiagramUIActionsPluginImages.java
@@ -173,6 +173,11 @@
public static final ImageDescriptor DESC_COPY_APPEARANCE_DISABLED = create(PREFIX_DISABLED
+ "copy_appearance_properties.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_GROUP = create(PREFIX_ENABLED + "group.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_GROUP_DISABLED = create(PREFIX_DISABLED + "group.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_UNGROUP = create(PREFIX_ENABLED + "ungroup.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_UNGROUP_DISABLED = create(PREFIX_DISABLED + "ungroup.gif"); //$NON-NLS-1$
+
/**
* Creates the image descriptor from the filename given.
*
diff --git a/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/AbstractModelerPropertySection.java b/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/AbstractModelerPropertySection.java
index 3b8a8f9..93531f7 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/AbstractModelerPropertySection.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/AbstractModelerPropertySection.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -38,6 +38,7 @@
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.common.ui.services.properties.PropertiesServiceAdapterFactory;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.diagram.ui.properties.internal.DiagramPropertiesDebugOptions;
import org.eclipse.gmf.runtime.diagram.ui.properties.internal.DiagramPropertiesPlugin;
@@ -119,10 +120,22 @@
.hasNext();) {
Object next = it.next();
- // unwrap down to EObject and add to the eObjects list
- if (addToEObjectList(next)) {
- input.add(next);
- }
+ if (digIntoGroups() && next instanceof GroupEditPart) {
+ for (Iterator iter = ((GroupEditPart) next)
+ .getFlattenedChildren().iterator(); iter.hasNext();) {
+ Object childEP = iter.next();
+ // unwrap down to EObject and add to the eObjects list
+ if (addToEObjectList(childEP)) {
+ input.add(childEP);
+ }
+ continue;
+ }
+ }
+ // unwrap down to EObject and add to the eObjects list
+ if (addToEObjectList(next)) {
+ input.add(next);
+ }
+
}
@@ -635,5 +648,15 @@
return DiagramPropertiesPlugin.getDefault()
.getUpdateRequestCollapser();
}
+
+ /**
+ * Override to return true to have this property section work on the shapes
+ * in a <code>GroupEditPart</code> as if the shapes were multi-selected.
+ *
+ * @return true if this property section is to dig into the shapes of groups
+ */
+ protected boolean digIntoGroups() {
+ return false;
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/appearance/ColorsAndFontsPropertySection.java b/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/appearance/ColorsAndFontsPropertySection.java
index 301631f..19f68f8 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/appearance/ColorsAndFontsPropertySection.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.properties/src/org/eclipse/gmf/runtime/diagram/ui/properties/sections/appearance/ColorsAndFontsPropertySection.java
@@ -721,4 +721,8 @@
}
super.dispose();
}
+
+ protected boolean digIntoGroups() {
+ return true;
+ }
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.providers/plugin.xml b/org.eclipse.gmf.runtime.diagram.ui.providers/plugin.xml
index 35fd018..ea9719d 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.providers/plugin.xml
+++ b/org.eclipse.gmf.runtime.diagram.ui.providers/plugin.xml
@@ -214,7 +214,7 @@
<partAction menubarPath="/diagramMenu/arrangeMenu/arrangeGroup" id="arrangeSelectionAction">
</partAction>
<partAction toolbarPath="/arrangeMenu/arrangeGroup" id="toolbarArrangeSelectionAction">
- </partAction>
+ </partAction>
<partMenu menubarPath="/diagramMenu/formatGroup" toolbarPath="/toolbarViewGroup" id="alignMenu">
</partMenu><partMenuGroup menubarPath="/diagramMenu/alignMenu/" toolbarPath="/alignMenu/" id="alignHorizontalGroup">
</partMenuGroup>
@@ -243,8 +243,7 @@
<partAction menubarPath="/diagramMenu/zorderMenu/zorderGroup" id="bringForwardAction">
</partAction>
<partAction menubarPath="/diagramMenu/zorderMenu/zorderGroup" id="sendBackwardAction">
- </partAction>
-
+ </partAction>
<partMenu menubarPath="/diagramMenu/viewGroup" id="viewMenu">
</partMenu>
<partMenuGroup menubarPath="/diagramMenu/viewMenu/" id="gridGroup">
@@ -416,18 +415,23 @@
<popupCustom path="/formatMenu/fontFillLineGroup" id="fillColorContributionItem">
</popupCustom>
<popupCustom path="/formatMenu/fontFillLineGroup" id="lineColorContributionItem">
- </popupCustom>
- <popupAction path="/addGroup" id="addNoteLinkAction">
- </popupAction>
+ </popupCustom>
<popupMenu path="/formatMenu/miscellaneousGroup" id="arrangeMenu">
</popupMenu>
<popupMenuGroup path="/formatMenu/arrangeMenu/" id="arrangeGroup">
</popupMenuGroup>
<popupAction path="/formatMenu/arrangeMenu/arrangeGroup" id="arrangeAllAction">
</popupAction>
- <popupAction path="/formatMenu/arrangeMenu/arrangeGroup" id="arrangeSelectionAction">
- </popupAction>
+ <popupAction path="/formatMenu/arrangeMenu/arrangeGroup" id="arrangeSelectionAction">
+ </popupAction>
</popupContribution>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.INotableEditPart">
+ </popupStructuredContributionCriteria>
+ <popupAction path="/addGroup" id="addNoteLinkAction">
+ </popupAction>
+ </popupContribution>
+
<!-- format and filter menu actions -->
<popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
@@ -462,7 +466,7 @@
<popupAction path="/formatMenu/zorderMenu/zorderGroup" id="bringForwardAction">
</popupAction>
<popupAction path="/formatMenu/zorderMenu/zorderGroup" id="sendBackwardAction">
- </popupAction>
+ </popupAction>
<popupAction path="/formatMenu/sizeGroup" id="autoSizeAction">
</popupAction>
@@ -477,7 +481,23 @@
<popupAction path="/filtersMenu/compartmentMenu/allCompartmentsGroup" id="noCompartmentsAction">
</popupAction>
</popupContribution>
-
+
+<!-- REMOVE ME BEFORE COMMITTING -->
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria
+ objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart"
+ objectCount="2+">
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="groupAction">
+ </popupAction>
+ </popupContribution>
+ <popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
+ <popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart">
+ </popupStructuredContributionCriteria>
+ <popupAction path="/formatMenu/miscellaneousGroup" id="ungroupAction">
+ </popupAction>
+ </popupContribution>
+
<popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
<popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart">
</popupStructuredContributionCriteria>
@@ -595,7 +615,7 @@
</popupStructuredContributionCriteria>
<popupAction path="/editGroup" id="deleteFromDiagramAction">
</popupAction>
- </popupContribution>
+ </popupContribution>
<popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
<popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.internal.editparts.IContainedEditPart">
<method name="getNotationView().getElement()" notValue="null">
@@ -604,6 +624,7 @@
<popupAction path="/editGroup" id="deleteFromModelAction">
</popupAction>
</popupContribution>
+
<popupContribution class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
<popupStructuredContributionCriteria objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.NoteEditPart" objectCount="1">
</popupStructuredContributionCriteria>
@@ -611,7 +632,7 @@
</popupStructuredContributionCriteria>
<popupAction path="/navigateMenu/openGroup" id="OpenAction">
</popupAction>
- </popupContribution>
+ </popupContribution>
<popupContribution
class="org.eclipse.gmf.runtime.diagram.ui.providers.DiagramContextMenuProvider">
<popupStructuredContributionCriteria
@@ -702,7 +723,7 @@
<Priority name="Lowest">
</Priority>
<object class="org.eclipse.gmf.runtime.notation.View" id="ShapesByType">
- <method name="getType()" value="Note, Text, NoteAttachment, DiagramName, Description">
+ <method name="getType()" value="Note, Text, NoteAttachment, DiagramName, Description, Group">
</method>
</object>
<context views="ShapesByType">
diff --git a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/DiagramContributionItemProvider.java b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/DiagramContributionItemProvider.java
index 44b789d..db2ccf1 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/DiagramContributionItemProvider.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/DiagramContributionItemProvider.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -43,6 +43,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.FontNameContributionItem;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.FontSizeContributionItem;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.FontStyleAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.GroupAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.HideConnectionLabelsAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.MakeSameSizeMenuManager;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.OpenWithMenuManager;
@@ -61,6 +62,7 @@
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.SnapBackAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.SnapToGridAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.SortFilterAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.UngroupAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.ViewGridAction;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.ViewMenuManager;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.ViewPageBreaksAction;
@@ -350,6 +352,12 @@
return new SelectConnectionEndAction(workbenchPage,true);
if (actionId.equals(ActionIds.SELECT_CONNECTION_TARGET))
return new SelectConnectionEndAction(workbenchPage,false);
+
+ if (actionId.equals(ActionIds.ACTION_GROUP))
+ return new GroupAction(workbenchPage);
+ if (actionId.equals(ActionIds.ACTION_UNGROUP))
+ return new UngroupAction(workbenchPage);
+
return super.createAction(actionId, partDescriptor);
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DefaultProvider.java b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DefaultProvider.java
index 714bde8..1a883bc 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DefaultProvider.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DefaultProvider.java
@@ -22,12 +22,14 @@
import java.util.Map;
import java.util.Set;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.graph.CompoundDirectedGraph;
import org.eclipse.draw2d.graph.DirectedGraph;
import org.eclipse.draw2d.graph.DirectedGraphLayout;
import org.eclipse.draw2d.graph.Edge;
@@ -44,6 +46,7 @@
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.common.core.util.Trace;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderedShapeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
@@ -59,7 +62,6 @@
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.jface.util.Assert;
/**
* Provider that creates a command for the DirectedGraph layout in GEF.
@@ -199,26 +201,26 @@
Point position = shapeEP.getLocation();
- // determine topleft most point, layout of items will be placed
- // starting at topleft point
- if (minX == -1) {
- minX = position.x;
- minY = position.y;
- } else {
- minX = Math.min(minX, position.x);
- minY = Math.min(minY, position.y);
- }
+ // determine topleft most point, layout of items will be placed
+ // starting at topleft point
+ if (minX == -1) {
+ minX = position.x;
+ minY = position.y;
+ } else {
+ minX = Math.min(minX, position.x);
+ minY = Math.min(minY, position.y);
+ }
Node n = new Node(shapeEP);
- n.setPadding(new Insets(NODE_PADDING));
+ n.setPadding(new Insets(NODE_PADDING));
Dimension size = shapeEP.getSize();
- setNodeMetrics(n, new Rectangle(position.x, position.y,
- size.width, size.height));
+ setNodeMetrics(n, new Rectangle(position.x, position.y,
+ size.width, size.height));
editPartToNodeDict.put(shapeEP, n);
nodes.add(n);
- }
+ }
}
return nodes;
@@ -340,13 +342,8 @@
to = to.getParent();
else if (shouldHandleListItems && to instanceof ListItemEditPart)
to = getFirstAnscestorinNodesMap(to, editPartToNodeDict);
- Node fromNode = (Node) editPartToNodeDict.get(from);
- Node toNode = (Node) editPartToNodeDict.get(to);
- if (fromNode != null && toNode != null
- && !fromNode.equals(toNode)) {
- addEdge(edges, poly, toNode, fromNode);
- }
+ addEdge(edges, poly, to, from, editPartToNodeDict);
}else{
notTopDownEdges.add(poly);
}
@@ -367,13 +364,7 @@
to = to.getParent();
else if (shouldHandleListItems && to instanceof ListItemEditPart)
to = getFirstAnscestorinNodesMap(to, editPartToNodeDict);
- Node fromNode = (Node) editPartToNodeDict.get(from);
- Node toNode = (Node) editPartToNodeDict.get(to);
-
- if (fromNode != null && toNode != null
- && !fromNode.equals(toNode)) {
- addEdge(edges, poly, fromNode, toNode);
- }
+ addEdge(edges, poly, from, to, editPartToNodeDict);
}
return edges;
}
@@ -385,11 +376,39 @@
* @param toNode
*/
private void addEdge(EdgeList edges, ConnectionEditPart connectionEP,
- Node fromNode, Node toNode) {
- Edge edge = new Edge(connectionEP, fromNode, toNode);
- initializeEdge(connectionEP, edge);
-
- edges.add(edge);
+ EditPart fromEP, EditPart toEP, Map editPartToNodeDict) {
+
+ Node fromNode = (Node) editPartToNodeDict.get(fromEP);
+ Node toNode = (Node) editPartToNodeDict.get(toEP);
+
+ if (fromNode != null && toNode != null && !fromNode.equals(toNode)) {
+
+ Edge edge = new Edge(connectionEP, fromNode, toNode);
+ initializeEdge(connectionEP, edge);
+ edges.add(edge);
+
+ // create edges to/from groups
+ boolean foundGroup = false;
+ if (fromEP.getParent() instanceof GroupEditPart) {
+ fromEP = fromEP.getParent();
+ foundGroup = true;
+ }
+ if (toEP.getParent() instanceof GroupEditPart) {
+ toEP = toEP.getParent();
+ foundGroup = true;
+ }
+ if (foundGroup) {
+ fromNode = (Node) editPartToNodeDict.get(fromEP);
+ toNode = (Node) editPartToNodeDict.get(toEP);
+
+ if (fromNode != null && toNode != null
+ && !fromNode.equals(toNode)) {
+
+ edges.add(new Edge("ImpliedGroupConnection", fromNode, //$NON-NLS-1$
+ toNode));
+ }
+ }
+ }
}
/**
@@ -740,11 +759,12 @@
Node source = null, target = null;
collectPoints(points, edge);
- cep = (ConnectionEditPart)edge.data;
- source = edge.source;
- target = edge.target;
- if (cep != null) {
+ if (edge.data instanceof ConnectionEditPart) {
+ cep = (ConnectionEditPart) edge.data;
+ source = edge.source;
+ target = edge.target;
+
PointListUtilities.normalizeSegments(points, MapModeUtil.getMapMode(cep.getFigure()).DPtoLP(3));
// Reset the points list
@@ -852,8 +872,8 @@
/**
* Creates the graph that will be used by the layouy provider
* Clients can override this method create different kind of graphs
- * This method is called by {@link DefaultProvider#layoutEditParts(GraphicalEditPart, IAdaptable) }
- * and {@link DefaultProvider#layoutEditParts(List, IAdaptable)}
+ * This method is called by {@link CopyOfDefaultProvider#layoutEditParts(GraphicalEditPart, IAdaptable) }
+ * and {@link CopyOfDefaultProvider#layoutEditParts(List, IAdaptable)}
* @return the Graph that will be used by the layout algorithm
*/
protected DirectedGraph createGraph(){
@@ -862,8 +882,8 @@
/**
* Creates the graph layout algorithm that will be used to layout the diagram
- * This method is called by {@link DefaultProvider#layoutEditParts(GraphicalEditPart, IAdaptable) }
- * and {@link DefaultProvider#layoutEditParts(List, IAdaptable)}
+ * This method is called by {@link CopyOfDefaultProvider#layoutEditParts(GraphicalEditPart, IAdaptable) }
+ * and {@link CopyOfDefaultProvider#layoutEditParts(List, IAdaptable)}
* @return the graph layout
*/
protected DirectedGraphLayout createGraphLayout() {
diff --git a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramEditPartProvider.java b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramEditPartProvider.java
index f49d078..29f1af7 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramEditPartProvider.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramEditPartProvider.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,7 @@
import org.eclipse.gmf.runtime.common.ui.services.parser.CommonParserHint;
import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.NoteEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.DescriptionCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.DiagramNameCompartmentEditPart;
@@ -46,6 +47,7 @@
{
shapeMap.put(ViewType.NOTE, NoteEditPart.class);
shapeMap.put(ViewType.TEXT, TextEditPart.class);
+ shapeMap.put(ViewType.GROUP, GroupEditPart.class);
}
/** list of supportted text editparts. */
private Map textCompartmentMap = new HashMap();
@@ -75,7 +77,7 @@
protected Class getNodeEditPartClass(View view){
String type = view.getType();
Class clazz = null;
- if(type!=null && type.length()>0){
+ if(type!=null && type.length()>0){
clazz = (Class)textCompartmentMap.get(type);
if(clazz==null)
clazz = (Class)shapeMap.get(type);
@@ -84,6 +86,7 @@
clazz = NoteEditPart.class;
}
}
+
return clazz;
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramIconProvider.java b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramIconProvider.java
index 4163e41..1684d67 100644
--- a/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramIconProvider.java
+++ b/org.eclipse.gmf.runtime.diagram.ui.providers/src/org/eclipse/gmf/runtime/diagram/ui/providers/internal/DiagramIconProvider.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,8 @@
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.common.ui.services.icon.IIconOperation;
import org.eclipse.gmf.runtime.common.ui.services.icon.IIconProvider;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
+import org.eclipse.gmf.runtime.diagram.ui.internal.l10n.DiagramUIPluginImages;
import org.eclipse.gmf.runtime.diagram.ui.internal.util.DiagramNotationType;
import org.eclipse.gmf.runtime.diagram.ui.l10n.SharedImages;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
@@ -53,11 +55,12 @@
if (view != null) {
if (DiagramViewProvider.isTextView(view)) {
return SharedImages.get(SharedImages.IMG_TEXT);
- }
-
- else if (DiagramViewProvider.isNoteView(view)) {
+ } else if (DiagramViewProvider.isNoteView(view)) {
return SharedImages.get(SharedImages.IMG_NOTE);
+ } else if (ViewType.GROUP.equals(view.getType())) {
+ return DiagramUIPluginImages
+ .get(DiagramUIPluginImages.IMG_GROUP);
}
} else if (hint.getAdapter(IElementType.class) != null) {
String fileName = (String) typeIconMap.get(hint);
@@ -80,11 +83,12 @@
}
View view = (View) adapter.getAdapter(View.class);
- if (view != null &&
- (DiagramViewProvider.isNoteView(view)
- || DiagramViewProvider.isTextView(view))) {
- return true;
- }
+ if (view != null
+ && (DiagramViewProvider.isNoteView(view)
+ || DiagramViewProvider.isTextView(view) || ViewType.GROUP
+ .equals(view.getType()))) {
+ return true;
+ }
if (oper.getHint().getAdapter(IElementType.class) != null) {
String fileName = (String) typeIconMap.get(oper.getHint());
diff --git a/org.eclipse.gmf.runtime.diagram.ui/icons/group.gif b/org.eclipse.gmf.runtime.diagram.ui/icons/group.gif
new file mode 100644
index 0000000..56b2a59
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui/icons/group.gif
Binary files differ
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/actions/ActionIds.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/actions/ActionIds.java
index 8dd0667..728e84b 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/actions/ActionIds.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/actions/ActionIds.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -79,7 +79,7 @@
public final String ACTION_TOOLBAR_ARRANGE_SELECTION = "toolbarArrangeSelectionAction"; //$NON-NLS-1$
public final String SELECT_CONNECTION_SOURCE = "selectConnectionSource"; //$NON-NLS-1$
public final String SELECT_CONNECTION_TARGET = "selectConnectionTarget"; //$NON-NLS-1$
- public final String ACTION_SELECT_ALL_SHAPES = "selectAllShapesAction"; //$NON-NLS-1$
+ public final String ACTION_SELECT_ALL_SHAPES = "selectAllShapesAction"; //$NON-NLS-1$
public final String ACTION_SELECT_ALL_CONNECTIONS = "selectAllConnectorsAction"; //$NON-NLS-1$
public final String ACTION_TOOLBAR_SELECT_ALL = "toolbarSelectAllAction"; //$NON-NLS-1$
public final String ACTION_TOOLBAR_SELECT_ALL_SHAPES = "toolbarSelectAllShapesAction"; //$NON-NLS-1$
@@ -102,6 +102,8 @@
public final String ACTION_SHOW_CONNECTION_LABELS = "showConnectorLabels"; //$NON-NLS-1$
public final String ACTION_HIDE_CONNECTION_LABELS = "hideConnectorLabels"; //$NON-NLS-1$
public final String ACTION_SHOW_COMPARTMENT_TITLE = "showCompartmentTitle"; //$NON-NLS-1$
+ public final String ACTION_GROUP = "groupAction"; //$NON-NLS-1$
+ public final String ACTION_UNGROUP = "ungroupAction"; //$NON-NLS-1$
/* The menu ID for the diagram editor popup menu */
public final String DIAGRAM_EDITOR_CONTEXT_MENU = "org.eclipse.gmf.runtime.diagram.ui.DiagramEditorContextMenu"; //$NON-NLS-1$
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/GroupEditPart.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/GroupEditPart.java
new file mode 100644
index 0000000..8e68f81
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/GroupEditPart.java
@@ -0,0 +1,160 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.ui.editparts;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.XYLayout;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;
+import org.eclipse.gef.requests.SelectionRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ContainerEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.DecorationEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.GroupComponentEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.GroupXYLayoutEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.NonResizableEditPolicyEx;
+import org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx;
+import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * The editpart for a group. A group is a special type of container around
+ * shapes.
+ *
+ * @author crevells, mmostafa
+ */
+public class GroupEditPart
+ extends ShapeEditPart {
+
+ class GroupFigure extends NodeFigure {
+ public boolean containsPoint(int x, int y) {
+ Point absolutePoint = new Point(x, y);
+ translateToAbsolute(absolutePoint);
+ for (Iterator iterator = getChildren().iterator(); iterator
+ .hasNext();) {
+ IFigure child = (IFigure) iterator.next();
+ Point pt = absolutePoint.getCopy();
+ child.translateToRelative(pt);
+ if (child.containsPoint(pt)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected boolean useLocalCoordinates() {
+ return true;
+ }
+ }
+
+ /**
+ * constructor
+ *
+ * @param view
+ * the view controlled by this edit part
+ */
+ public GroupEditPart(View view) {
+ super(view);
+ }
+
+ protected IFigure createFigure() {
+ IFigure f = new GroupFigure();
+ f.setLayoutManager(new XYLayout());
+ f.setOpaque(false);
+ return f;
+ }
+
+ public DragTracker getDragTracker(Request request) {
+
+ // we only want to select the group if the user clicked the area
+ // over one of the shapes in the group
+ if (request instanceof SelectionRequest) {
+
+ for (Iterator iterator = getChildren().iterator(); iterator
+ .hasNext();) {
+ IGraphicalEditPart childEP = (IGraphicalEditPart) iterator
+ .next();
+ Point location = ((SelectionRequest) request).getLocation()
+ .getCopy();
+
+ childEP.getFigure().translateToRelative(location);
+
+ if (childEP.getFigure().containsPoint(location)) {
+ return super.getDragTracker(request);
+ }
+ }
+
+ // in this case the user has not clicked over one of the shapes,
+ // so disable selection; however, we must still support dragging
+ // to move the group if it is already selected.
+ return new DragEditPartsTrackerEx(this) {
+
+ protected boolean handleButtonDown(int button) {
+ int selectedState = getSelected();
+ if (selectedState == SELECTED
+ || selectedState == SELECTED_PRIMARY) {
+ return super.handleButtonDown(button);
+ }
+
+ // do nothing if the group isn't selected
+ return true;
+ }
+
+ };
+ }
+
+ return super.getDragTracker(request);
+ }
+
+ protected void createDefaultEditPolicies() {
+ installEditPolicy(EditPolicyRoles.DECORATION_ROLE,
+ new DecorationEditPolicy());
+ installEditPolicy(EditPolicy.LAYOUT_ROLE, new GroupXYLayoutEditPolicy());
+ installEditPolicy(EditPolicy.COMPONENT_ROLE,
+ new GroupComponentEditPolicy());
+ installEditPolicy(EditPolicy.CONTAINER_ROLE, new ContainerEditPolicy());
+ installEditPolicy(EditPolicyRoles.SNAP_FEEDBACK_ROLE,
+ new SnapFeedbackPolicy());
+ }
+
+ public EditPolicy getPrimaryDragEditPolicy() {
+ return new NonResizableEditPolicyEx();
+ }
+
+ /**
+ * Gets all the shape children of this group, digging into any nested groups
+ * found.
+ *
+ * @return all the shape children including shapes in nested groups
+ */
+ public List getFlattenedChildren() {
+ List flatChildren = new ArrayList(getChildren().size());
+ for (Iterator iter = getChildren().iterator(); iter.hasNext();) {
+ Object childEP = iter.next();
+ if (childEP instanceof GroupEditPart) {
+ flatChildren.addAll(((GroupEditPart) childEP)
+ .getFlattenedChildren());
+ } else {
+ flatChildren.add(childEP);
+ }
+ }
+ return flatChildren;
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/ShapeEditPart.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/ShapeEditPart.java
index 3f82a79..eec8378 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/ShapeEditPart.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/ShapeEditPart.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,13 +11,19 @@
package org.eclipse.gmf.runtime.diagram.ui.editparts;
+import java.util.Iterator;
+
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.requests.SelectionRequest;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ComponentEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ContainerEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
@@ -28,12 +34,9 @@
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
-/*
- * @canBeSeenBy %partners
- */
/**
* the base controler for shapes
- * @author mmostafa
+ * @author mmostafa, crevells
*
*/
public abstract class ShapeEditPart extends TopGraphicEditPart implements IPrimaryEditPart {
@@ -144,4 +147,54 @@
public EditPolicy getPrimaryDragEditPolicy() {
return new ResizableShapeEditPolicy();
}
+
+ public EditPart getTargetEditPart(Request request) {
+
+ if (RequestConstants.REQ_SELECTION == request.getType()
+ && getParent() instanceof GroupEditPart) {
+
+ // If the shape is already selected then do not give up selection to
+ // the group.
+ if (getSelected() != SELECTED_NONE) {
+ return super.getTargetEditPart(request);
+ }
+
+ GroupEditPart groupEP = (GroupEditPart) getParent();
+
+ // Normally when a shape is not selected, the right-mouse button
+ // will cause the shape to be selected and the context menu to show.
+ // If the shape is in a group, we do not want this behavior as we
+ // want the context menu of the group to show.
+ if (getSelected() == SELECTED_NONE
+ && (request instanceof SelectionRequest)
+ && ((SelectionRequest) request).getLastButtonPressed() == 3) {
+ return groupEP.getTargetEditPart(request);
+ }
+
+ // If the group is currently selected, then this is the second click
+ // then the shape should be selected.
+ if (groupEP.getSelected() != SELECTED_NONE) {
+ return super.getTargetEditPart(request);
+ }
+
+ // If any of the group's children are currently selected then the
+ // selection of another child of the group will result in the child
+ // being selected and not the group.
+ for (Iterator iter = groupEP.getChildren().iterator(); iter
+ .hasNext();) {
+ EditPart childEP = (EditPart) iter.next();
+ if (childEP.getSelected() != SELECTED_NONE) {
+ return super.getTargetEditPart(request);
+ }
+
+ }
+
+ // otherwise we want the group to get selected
+ return groupEP.getTargetEditPart(request);
+ }
+
+ return super.getTargetEditPart(request);
+ }
+
+
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/TreeContainerEditPart.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/TreeContainerEditPart.java
index aacf9d9..3d575b8 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/TreeContainerEditPart.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editparts/TreeContainerEditPart.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,11 +11,12 @@
package org.eclipse.gmf.runtime.diagram.ui.editparts;
+import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
/**
* Implementation for the regular tree edit part
@@ -40,9 +41,9 @@
* @return List of children.
*/
protected List getModelChildren() {
- if (getModel() instanceof Diagram)
- return ((Diagram) getModel()).getChildren();
- return null;
+ if (getModel() instanceof View)
+ return ((View) getModel()).getChildren();
+ return Collections.EMPTY_LIST;
}
/**
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalConnectionEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalConnectionEditPolicy.java
index 57c1c62..3818b1a 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalConnectionEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalConnectionEditPolicy.java
@@ -35,6 +35,7 @@
import org.eclipse.gmf.runtime.diagram.ui.commands.DeferredLayoutCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetViewMutabilityCommand;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.INodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.figures.ICanonicalShapeCompartmentLayout;
@@ -125,9 +126,18 @@
View tgt = (View) tep.getAdapter(View.class);
if (src != null && tgt != null) {
- return sep.getParent().getEditPolicy(
+ EditPart sourceParent = sep.getParent();
+ while (sourceParent instanceof GroupEditPart) {
+ sourceParent = sourceParent.getParent();
+ }
+ EditPart targetParent = sep.getParent();
+ while (targetParent instanceof GroupEditPart) {
+ targetParent = targetParent.getParent();
+ }
+
+ return sourceParent.getEditPolicy(
EditPolicyRoles.CANONICAL_ROLE) != null
- && tep.getParent().getEditPolicy(
+ && targetParent.getEditPolicy(
EditPolicyRoles.CANONICAL_ROLE) != null;
}
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalEditPolicy.java
index 8b110b8..cda7dae 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CanonicalEditPolicy.java
@@ -54,6 +54,7 @@
import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
import org.eclipse.gmf.runtime.diagram.core.listener.NotificationUtil;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
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;
@@ -942,17 +943,40 @@
/**
- * Return the host's model children.
- * @return list of <code>View</Code>s
- */
- protected List getViewChildren() {
- return new ArrayList(((View)host().getModel()).getChildren());
-
- }
+ * Return the host's model children.
+ *
+ * @return list of <code>View</Code>s
+ */
+ protected List getViewChildren() {
+ return getViewChildren((View) host().getModel());
+ }
+
+ /**
+ * Return the host's model children. This is a recursive method that handles
+ * groups.
+ *
+ * @param view
+ * the view to find the children for
+ * @return list of children views with groups removed.
+ */
+ private List getViewChildren(View view) {
+ ArrayList list = new ArrayList();
+ for (Iterator iter = view.getChildren().iterator(); iter.hasNext();) {
+
+ Object child = iter.next();
+ if (child instanceof Node
+ && ViewType.GROUP.equals(((Node) child).getType())) {
+ list.addAll(getViewChildren((View) child));
+ } else {
+ list.add(child);
+ }
+ }
+ return list;
+ }
/**
- * Resynchronize the canonical container.
- */
+ * Resynchronize the canonical container.
+ */
public final void refresh() {
try {
if ( isEnabled() ) {
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ComponentEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ComponentEditPolicy.java
index 9e37a5b..e81b5a0 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ComponentEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ComponentEditPolicy.java
@@ -27,6 +27,7 @@
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IInsertableEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.SemanticListCompartmentEditPart;
@@ -100,8 +101,16 @@
(SemanticListCompartmentEditPart)parent;
return semListCompartment.isCanonicalOn();
+ } else {
+
+ // If the parent is a group, then we want to get the first parent
+ // that isn't a group and test for a canonical editpolicy there.
+ while (parent instanceof GroupEditPart) {
+ parent = parent.getParent();
+ }
}
+
if (parent instanceof IGraphicalEditPart) {
CanonicalEditPolicy cep = (CanonicalEditPolicy)parent.getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
if ( cep != null ) {
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java
index 9eddb7e..c2f8b4c 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,6 +16,7 @@
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
@@ -36,6 +37,7 @@
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.util.ObjectAdapter;
import org.eclipse.gmf.runtime.common.ui.util.ICustomData;
+import org.eclipse.gmf.runtime.diagram.core.commands.GroupCommand;
import org.eclipse.gmf.runtime.diagram.core.internal.commands.BringForwardCommand;
import org.eclipse.gmf.runtime.diagram.core.internal.commands.BringToFrontCommand;
import org.eclipse.gmf.runtime.diagram.core.internal.commands.SendBackwardCommand;
@@ -45,12 +47,14 @@
import org.eclipse.gmf.runtime.diagram.ui.commands.DeferredLayoutCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ListItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.commands.DuplicateViewsCommand;
import org.eclipse.gmf.runtime.diagram.ui.internal.commands.PasteCommand;
import org.eclipse.gmf.runtime.diagram.ui.internal.commands.RefreshEditPartCommand;
+import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.IEditableEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.ISurfaceEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.requests.PasteViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.internal.services.layout.IInternalLayoutRunnable;
@@ -420,8 +424,11 @@
* @see org.eclipse.gef.EditPolicy#getCommand(Request)
*/
public Command getCommand(Request request) {
-
- if (request instanceof ArrangeRequest) {
+ if (ActionIds.ACTION_GROUP.equals(request.getType())
+ && request instanceof GroupRequest) {
+ return getGroupCommand((GroupRequest) request);
+ }
+ else if (request instanceof ArrangeRequest) {
return getArrangeCommand((ArrangeRequest)request);
}
@@ -471,7 +478,55 @@
return super.getCommand(request);
}
- /**
+ /**
+ * Returns a command to group the editparts in the request.
+ *
+ * @param request
+ * the request containing the editparts to be grouped.
+ * @return the command to perform the grouping
+ */
+ protected Command getGroupCommand(GroupRequest request) {
+ List shapeViews = new LinkedList();
+ IGraphicalEditPart parentEP = null;
+ for (Iterator iter = request.getEditParts().iterator(); iter.hasNext();) {
+ Object editpart = iter.next();
+
+ if (editpart instanceof ShapeEditPart) {
+
+ if (!((IEditableEditPart) editpart).isEditModeEnabled()) {
+ return null;
+ }
+
+ if (editpart instanceof IBorderItemEditPart) {
+ return null;
+ }
+
+ if (parentEP != null) {
+ if (parentEP != ((ShapeEditPart) editpart).getParent()) {
+ // can only group shapes with the same parent
+ return null;
+ }
+ } else {
+ parentEP = (IGraphicalEditPart) ((ShapeEditPart) editpart)
+ .getParent();
+ }
+
+ if (((ShapeEditPart) editpart).getModel() instanceof Node) {
+ shapeViews.add(((ShapeEditPart) editpart).getModel());
+ }
+ }
+ }
+
+ if (parentEP == null || !parentEP.isEditModeEnabled()) {
+ return null;
+ }
+
+ GroupCommand cmd = new GroupCommand(((IGraphicalEditPart) getHost())
+ .getEditingDomain(), shapeViews);
+ return new ICommandProxy(cmd);
+ }
+
+ /**
* @see org.eclipse.gef.EditPolicy#getTargetEditPart(org.eclipse.gef.Request)
*/
public EditPart getTargetEditPart(Request request) {
@@ -486,6 +541,7 @@
ActionIds.ACTION_ARRANGE_ALL.equals(request.getType())
|| ActionIds.ACTION_TOOLBAR_ARRANGE_ALL.equals(request.getType())
|| ActionIds.ACTION_ARRANGE_SELECTION.equals(request.getType())
+ || ActionIds.ACTION_GROUP.equals(request.getType())
|| ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION.equals(request.getType())
|| RequestConstants.REQ_ARRANGE_RADIAL.equals(request.getType())
|| RequestConstants.REQ_ARRANGE_DEFERRED.equals(request.getType())
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CreationEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CreationEditPolicy.java
index 51496fd..489842f 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CreationEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/CreationEditPolicy.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -46,6 +47,7 @@
import org.eclipse.gmf.runtime.diagram.ui.commands.CreateOrSelectElementCommand;
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.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
@@ -61,7 +63,6 @@
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.jface.util.Assert;
import org.eclipse.swt.widgets.Display;
/**
@@ -151,6 +152,9 @@
if ( ep instanceof LabelEditPart ) {
continue;
}
+ if (ep instanceof GroupEditPart) {
+ cc.compose(getReparentGroupCommand((GroupEditPart) ep));
+ }
View view = (View)ep.getAdapter(View.class);
if ( view == null ) {
@@ -167,13 +171,57 @@
}
return cc.isEmpty() ? null : new ICommandProxy(cc.reduce());
}
-
- /**
- * Return the command to reparent the supplied editpart's semantic and notation
- * elements.
- * @param gep the editpart being reparented
- * @return A CompositeCommand2 that will reparent both the semantic and notation elements.
- */
+
+ /**
+ * Return the command to reparent the supplied group editpart's semantic and
+ * notation elements.
+ *
+ * @param gep
+ * the groupEP editpart being reparented
+ * @return A composite command that will reparent both the semantic and
+ * notation elements of the group.
+ */
+ protected ICommand getReparentGroupCommand(GroupEditPart groupEP) {
+ CompositeCommand cc = new CompositeCommand(
+ DiagramUIMessages.AddCommand_Label);
+ View container = (View) getHost().getModel();
+ EObject context = ViewUtil.resolveSemanticElement(container);
+
+ // semantic
+ TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost())
+ .getEditingDomain();
+ for (Iterator iter = groupEP.getFlattenedChildren().iterator(); iter
+ .hasNext();) {
+ IGraphicalEditPart childEP = (IGraphicalEditPart) iter.next();
+ EObject element = ViewUtil.resolveSemanticElement((View) childEP
+ .getModel());
+ if (element != null) {
+ Command moveSemanticCmd = getHost().getCommand(
+ new EditCommandRequestWrapper(new MoveRequest(
+ editingDomain, context, element)));
+
+ if (moveSemanticCmd == null) {
+ return org.eclipse.gmf.runtime.common.core.command.UnexecutableCommand.INSTANCE;
+ }
+
+ cc.compose(new CommandProxy(moveSemanticCmd));
+ }
+ }
+
+ // notation
+ cc.compose(getReparentViewCommand(groupEP));
+ return cc;
+ }
+
+ /**
+ * Return the command to reparent the supplied editpart's semantic and
+ * notation elements.
+ *
+ * @param gep
+ * the editpart being reparented
+ * @return A CompositeCommand2 that will reparent both the semantic and
+ * notation elements.
+ */
protected ICommand getReparentCommand( IGraphicalEditPart gep ) {
CompositeCommand cc = new CompositeCommand(DiagramUIMessages.AddCommand_Label);
View container = (View)getHost().getModel();
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/DiagramDragDropEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/DiagramDragDropEditPolicy.java
index 4228aee..a6d726c 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/DiagramDragDropEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/DiagramDragDropEditPolicy.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -22,6 +22,7 @@
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ListCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest;
@@ -141,7 +142,11 @@
if (cmd != null) {
return cmd;
}
- }
+ } else if (parentEP instanceof GroupEditPart) {
+ // Dragging shapes outside the group will cause the group to
+ // grow and thus should not reparent.
+ return null;
+ }
}
return super.getDropCommand(request);
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupComponentEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupComponentEditPolicy.java
new file mode 100644
index 0000000..e98e8c0
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupComponentEditPolicy.java
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.ui.editpolicies;
+
+import java.util.Iterator;
+
+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.commands.CompoundCommand;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gmf.runtime.diagram.core.commands.UngroupCommand;
+import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
+import org.eclipse.gmf.runtime.diagram.ui.requests.GroupRequestViaKeyboard;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
+import org.eclipse.gmf.runtime.notation.Node;
+
+/**
+ * A <code>ComponentEditPolicy</code> for a <code>GroupEditPart</code>.
+ *
+ * @author crevells
+ */
+public class GroupComponentEditPolicy
+ extends ComponentEditPolicy {
+
+
+ public boolean understandsRequest(Request request) {
+ if (ActionIds.ACTION_UNGROUP.equals(request.getType())) {
+ return true;
+ }
+ return super.understandsRequest(request);
+ }
+
+ public Command getCommand(Request request) {
+ if (ActionIds.ACTION_UNGROUP.equals(request.getType())) {
+ return getUngroupCommand(request);
+ }
+ return super.getCommand(request);
+ }
+
+ public EditPart getTargetEditPart(Request request) {
+ return understandsRequest(request) ? getHost()
+ : null;
+ }
+
+ /**
+ * Returns a command to ungroup and then delete the group in the request.
+ *
+ * @param request
+ * the request containing the group to be ungrouped
+ * @return the command to perform the ungrouping
+ */
+ protected Command getUngroupCommand(Request request) {
+ UngroupCommand cmd = new UngroupCommand(((GroupEditPart) getHost())
+ .getEditingDomain(), (Node) getHost().getModel());
+ return new ICommandProxy(cmd);
+ }
+
+ protected Command createDeleteSemanticCommand(GroupRequest deleteRequest) {
+ TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost())
+ .getEditingDomain();
+
+ boolean shouldShowPrompt = (deleteRequest instanceof GroupRequestViaKeyboard) ? ((GroupRequestViaKeyboard) deleteRequest)
+ .isShowInformationDialog()
+ : false;
+
+ EditCommandRequestWrapper editCommandRequest = new EditCommandRequestWrapper(
+ new DestroyElementRequest(editingDomain, shouldShowPrompt),
+ deleteRequest.getExtendedData());
+
+ CompoundCommand cc = new CompoundCommand();
+ for (Iterator iter = ((GroupEditPart) getHost()).getFlattenedChildren()
+ .iterator(); iter.hasNext();) {
+ IGraphicalEditPart childEP = (IGraphicalEditPart) iter.next();
+ Command semanticCmd = childEP.getCommand(editCommandRequest);
+ if (semanticCmd != null && semanticCmd.canExecute()) {
+ cc.add(semanticCmd);
+ }
+ }
+
+ if (!cc.isEmpty()) {
+ cc.add(createDeleteViewCommand(deleteRequest));
+ return cc;
+ }
+
+ return createDeleteViewCommand(deleteRequest);
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupXYLayoutEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupXYLayoutEditPolicy.java
new file mode 100644
index 0000000..da273e4
--- /dev/null
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/GroupXYLayoutEditPolicy.java
@@ -0,0 +1,87 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.runtime.diagram.ui.editpolicies;
+
+import java.util.Iterator;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.CompoundCommand;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.core.internal.commands.AdjustGroupLocationCommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * A <code>XYLayoutEditPolicy</code> for a <code>GroupEditPart</code>.
+ *
+ * @author crevells
+ */
+public class GroupXYLayoutEditPolicy
+ extends XYLayoutEditPolicy {
+
+ public boolean understandsRequest(Request req) {
+ if (RequestConstants.REQ_AUTOSIZE.equals(req.getType())) {
+ return true;
+ }
+ return super.understandsRequest(req);
+ }
+
+ public Command getCommand(Request request) {
+ if (RequestConstants.REQ_AUTOSIZE.equals(request.getType()))
+ return getCommandFromChildren(request);
+ return super.getCommand(request);
+ }
+
+ /**
+ * Overridden so that if a child shape is moved or resized such that the
+ * group's location (i.e. top left corner) changes, the group's location as
+ * well as all the children's relative locations are updated.
+ */
+ protected Command getResizeChildrenCommand(ChangeBoundsRequest request) {
+ CompoundCommand resize = new CompoundCommand();
+ resize.add(super.getResizeChildrenCommand(request));
+ resize.add(new ICommandProxy(new AdjustGroupLocationCommand(
+ ((IGraphicalEditPart) getHost()).getEditingDomain(),
+ (View) getHost().getModel())));
+ return resize;
+ }
+
+ public EditPart getTargetEditPart(Request request) {
+ if (REQ_CREATE.equals(request.getType())) {
+ return null;
+ } else if (RequestConstants.REQ_AUTOSIZE.equals(request.getType())) {
+ return getHost();
+ }
+ return super.getTargetEditPart(request);
+ }
+
+ /**
+ * Gets a command from each child in the group.
+ *
+ * @param request
+ * @return the compound command
+ */
+ private Command getCommandFromChildren(Request request) {
+ CompoundCommand cc = new CompoundCommand();
+ for (Iterator iter = getHost().getChildren().iterator(); iter.hasNext();) {
+ EditPart childEP = (EditPart) iter.next();
+ cc.add(childEP.getCommand(request));
+ }
+ cc.unwrap();
+ return cc;
+ }
+
+}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ShapeCompartmentDropEditPolicy.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ShapeCompartmentDropEditPolicy.java
index 874df7d..e0bdad1 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ShapeCompartmentDropEditPolicy.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ShapeCompartmentDropEditPolicy.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -26,6 +26,7 @@
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
@@ -59,7 +60,11 @@
IGraphicalEditPart gep = (IGraphicalEditPart)getHost();
if (gep.getTopGraphicEditPart().equals(requestEP)) {
return null;
- }
+ } else if (requestEP.getParent() instanceof GroupEditPart) {
+ // Dragging shapes outside the group will cause the
+ // group to grow and thus should not reparent.
+ return null;
+ }
}
}
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/ToggleCanonicalModeCommand.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/ToggleCanonicalModeCommand.java
index b3cb6c2..8a3a58a 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/ToggleCanonicalModeCommand.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/ToggleCanonicalModeCommand.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -28,6 +28,7 @@
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
@@ -139,9 +140,18 @@
* @param editPart edit part to use
* @return the canoncial edit policy if there is any
*/
- protected static CanonicalEditPolicy getCanonicalEditPolicy( EditPart editPart ) {
- return (CanonicalEditPolicy)editPart.getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
- }
+ protected static CanonicalEditPolicy getCanonicalEditPolicy(
+ EditPart editPart) {
+
+ // If the editpart is a group, then we want to get the first parent
+ // that isn't a group and get the canonical editpolicy there.
+ while (editPart instanceof GroupEditPart) {
+ editPart = editPart.getParent();
+ }
+
+ return (CanonicalEditPolicy) editPart
+ .getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
+ }
/** Removes the canonical editpolict from the target editpart. */
public void execute() {
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/l10n/DiagramUIPluginImages.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/l10n/DiagramUIPluginImages.java
index 4c3759a..bf9aec6 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/l10n/DiagramUIPluginImages.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/internal/l10n/DiagramUIPluginImages.java
@@ -63,6 +63,8 @@
public static final String IMG_POPUPBAR = PREFIX_ROOT + "popupbar.gif"; //$NON-NLS-1$
public static final String IMG_POPUPBAR_PLUS = PREFIX_ROOT + "popupbar_plus.gif"; //$NON-NLS-1$
+ public static final String IMG_GROUP = PREFIX_ROOT + "group.gif"; //$NON-NLS-1$
+
// Image descriptors.
public static final ImageDescriptor DESC_HANDLE_COLLAPSE = createAndCache(IMG_HANDLE_COLLAPSE);
@@ -187,7 +189,9 @@
public static final ImageDescriptor DESC_DOWN_PATH = create(PREFIX_ROOT + "CollectionDown.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_SORT_ARROW_UP = create(PREFIX_ROOT + "sm_arrow_up.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_SORT_ARROW_DN = create(PREFIX_ROOT + "sm_arrow_dn.gif"); //$NON-NLS-1$
-
+
+ public static final ImageDescriptor DESC_GROUP = createAndCache(IMG_GROUP);
+
/**
* Creates the image descriptor from the filename given.
*
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/parts/DiagramEditor.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/parts/DiagramEditor.java
index 7e41fca..ed2e6a8 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/parts/DiagramEditor.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/parts/DiagramEditor.java
@@ -27,6 +27,7 @@
import org.eclipse.core.commands.operations.ObjectUndoContext;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
@@ -76,11 +77,13 @@
import org.eclipse.gmf.runtime.common.ui.util.IPartSelector;
import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewType;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IDiagramPreferenceSupport;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.TreeContainerEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.TreeDiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.TreeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions;
@@ -113,7 +116,6 @@
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
@@ -131,7 +133,6 @@
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInSource;
@@ -151,7 +152,7 @@
implements IDiagramWorkbenchPart, ITabbedPropertySheetPageContributor,
IShowInSource {
- public static String DIAGRAM_CONTEXT_ID = "org.eclipse.gmf.runtime.diagram.ui.diagramContext";
+ public static String DIAGRAM_CONTEXT_ID = "org.eclipse.gmf.runtime.diagram.ui.diagramContext"; //$NON-NLS-1$
/**
* teh ID of the outline
@@ -1517,12 +1518,15 @@
return new EditPartFactory() {
public EditPart createEditPart(EditPart context, Object model) {
- if (model instanceof Diagram) {
- return new TreeDiagramEditPart(model);
- } else {
- return new TreeEditPart(model);
- }
- }
+ if (model instanceof Diagram) {
+ return new TreeDiagramEditPart(model);
+ } else if (model instanceof View
+ && ViewType.GROUP.equals(((View) model).getType())) {
+ return new TreeContainerEditPart(model);
+ } else {
+ return new TreeEditPart(model);
+ }
+ }
};
}
diff --git a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/tools/DragEditPartsTrackerEx.java b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/tools/DragEditPartsTrackerEx.java
index c9243a6..11a63c6 100644
--- a/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/tools/DragEditPartsTrackerEx.java
+++ b/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/tools/DragEditPartsTrackerEx.java
@@ -1,5 +1,5 @@
/******************************************************************************
- * Copyright (c) 2002, 2006 IBM Corporation and others.
+ * Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -26,6 +26,7 @@
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.tools.DragEditPartsTracker;
import org.eclipse.gef.tools.ToolUtilities;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.DuplicateRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
@@ -197,6 +198,43 @@
}
return super.calculateCursor();
}
-
+ protected boolean handleButtonDown(int button) {
+
+ // If the group is selected, and the user clicks on a shape, defer the
+ // selection of the shape until the mouse button is released instead of
+ // selecting on mouse down because if the user does a drag they will
+ // move the entire group and not the shape.
+ if (button == 1
+ && getSourceEditPart().getParent() instanceof GroupEditPart
+ && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) {
+
+ stateTransition(STATE_INITIAL, STATE_DRAG);
+ return true;
+ }
+
+ return super.handleButtonDown(button);
+ }
+
+ protected boolean handleDoubleClick(int button) {
+ // If the user double-clicks a shape in a group and the shape is not
+ // selected, select the shape.
+ if (getSourceEditPart().getParent() instanceof GroupEditPart
+ && getSourceEditPart().getSelected() == EditPart.SELECTED_NONE) {
+ performSelection();
+ return true;
+ } else {
+ return super.handleDoubleClick(button);
+ }
+ }
+
+ protected void performSelection() {
+ super.performSelection();
+
+ // If the new selection is a child of a group, we want to deselect the group.
+ if (getSourceEditPart().getParent() instanceof GroupEditPart
+ && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) {
+ getCurrentViewer().deselect(getSourceEditPart().getParent());
+ }
+ }
}
diff --git a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/AllTests.java b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/AllTests.java
index d009c7c..d1b9b5c 100644
--- a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/AllTests.java
+++ b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/AllTests.java
@@ -25,6 +25,8 @@
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.DiagramAssistantTests;
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.DiagramEventBrokerTests;
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.DiagramGraphicalViewerTests;
+import org.eclipse.gmf.tests.runtime.diagram.ui.logic.GroupTests;
+import org.eclipse.gmf.tests.runtime.diagram.ui.logic.GroupsInCompartmentTests;
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.LogicCanonicalTests;
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.LogicCreationTests;
import org.eclipse.gmf.tests.runtime.diagram.ui.logic.LogicDiagramTests;
@@ -78,7 +80,9 @@
suite.addTest(DiagramEditingDomainTestCase.suite());
suite.addTest(CommandUtilitiesTest.suite());
suite.addTest(DiagramEventBrokerServiceTests.suite());
-
+ suite.addTest(GroupTests.suite());
+ suite.addTest(GroupsInCompartmentTests.suite());
+
return suite;
}
diff --git a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupTests.java b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupTests.java
new file mode 100644
index 0000000..24abf24
--- /dev/null
+++ b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupTests.java
@@ -0,0 +1,1119 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.tests.runtime.diagram.ui.logic;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.Tool;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.palette.ToolEntry;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.gmf.examples.runtime.diagram.logic.internal.LogicDiagramPlugin;
+import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.GroupAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.SelectAllAction;
+import org.eclipse.gmf.runtime.diagram.ui.actions.internal.UngroupAction;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.geoshapes.internal.providers.GeoshapeType;
+import org.eclipse.gmf.runtime.diagram.ui.internal.util.DiagramNotationType;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.tests.runtime.diagram.ui.AbstractTestBase;
+import org.eclipse.gmf.tests.runtime.diagram.ui.util.ITestActionCallback;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * Tests for group and ungroup functionality.
+ *
+ * @author crevells
+ */
+public class GroupTests
+ extends AbstractTestBase {
+
+ public static Test suite() {
+ TestSuite s = new TestSuite(GroupTests.class);
+ return s;
+ }
+
+ public GroupTests() {
+ super("Group Tests");//$NON-NLS-1$
+ }
+
+ public class GroupTestFixture
+ extends LogicTestFixture {
+
+ protected void createShapesAndConnectors()
+ throws Exception {
+ // do nothing, each test will create the shapes it wants
+ }
+
+ public void openDiagram()
+ throws Exception {
+ super.openDiagram();
+
+ // Expand the diagram since these tests simulate mouse clicks
+ // and it is necessary that the diagram be completely visible in
+ // the viewport.
+ IEditorReference[] editors = getWorkbenchPage().findEditors(
+ ((DiagramEditor) getDiagramWorkbenchPart()).getEditorInput(),
+ LogicDiagramPlugin.EDITOR_ID, IWorkbenchPage.MATCH_ID);
+ getWorkbenchPage().setPartState(editors[0],
+ IWorkbenchPage.STATE_MAXIMIZED);
+ }
+ }
+
+ protected void setTestFixture() {
+ testFixture = new GroupTestFixture();
+ }
+
+ protected LogicTestFixture getFixture() {
+ return (LogicTestFixture) testFixture;
+ }
+
+ protected View note1View;
+
+ protected View note2View;
+
+ protected View geoshape1View;
+
+ protected View geoshape2View;
+
+ /**
+ * Adds two notes and two geoshapes and some connections between them. Look
+ * at the details of the method to see what gets created.
+ */
+ protected void setupShapes() {
+ ShapeEditPart note1EP = getFixture().createShapeUsingTool(
+ DiagramNotationType.NOTE, new Point(10, 10), getContainerEP(),
+ new Dimension(50, 50));
+
+ ShapeEditPart note2EP = getFixture().createShapeUsingTool(
+ DiagramNotationType.NOTE, new Point(100, 10), getContainerEP(),
+ new Dimension(50, 50));
+
+ ShapeEditPart geoshape1EP = getFixture().createShapeUsingTool(
+ GeoshapeType.CYLINDER, new Point(10, 100), getContainerEP(),
+ new Dimension(50, 50));
+
+ ShapeEditPart geoshape2EP = getFixture().createShapeUsingTool(
+ GeoshapeType.DIAMOND, new Point(100, 100), getContainerEP(),
+ new Dimension(50, 50));
+
+ flushEventQueue();
+
+ // Cache the views so we can find the editparts again later.
+ note1View = (View) note1EP.getModel();
+ note2View = (View) note2EP.getModel();
+ geoshape1View = (View) geoshape1EP.getModel();
+ geoshape2View = (View) geoshape2EP.getModel();
+
+ // Create some connections just to make things more complicated.
+ getFixture().createConnectorUsingTool(note1EP, geoshape1EP,
+ GeoshapeType.LINE);
+ getFixture().createConnectorUsingTool(note2EP, geoshape1EP,
+ DiagramNotationType.NOTE_ATTACHMENT);
+ getFixture().createConnectorUsingTool(note2EP, geoshape2EP,
+ DiagramNotationType.NOTE_ATTACHMENT);
+ getFixture().createConnectorUsingTool(geoshape1EP, geoshape2EP,
+ GeoshapeType.LINE);
+
+ flushEventQueue();
+ }
+
+ protected IGraphicalEditPart getContainerEP() {
+ return getDiagramEditPart();
+ }
+
+ protected ShapeEditPart getNote1EP() {
+ return (ShapeEditPart) findEditPart(note1View);
+ }
+
+ protected ShapeEditPart getNote2EP() {
+ return (ShapeEditPart) findEditPart(note2View);
+ }
+
+ protected ShapeEditPart getGeoshape1EP() {
+ return (ShapeEditPart) findEditPart(geoshape1View);
+ }
+
+ protected ShapeEditPart getGeoshape2EP() {
+ return (ShapeEditPart) findEditPart(geoshape2View);
+ }
+
+ protected void setupShapesAndGroups() {
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+
+ GroupEditPart groupEP = groupShapes(shapes);
+
+ shapes.clear();
+ shapes.add(groupEP);
+ shapes.add(getNote2EP());
+
+ groupShapes(shapes);
+
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+ assertEquals(2, getInnerGroupEP().getChildren().size());
+ }
+
+ protected GroupEditPart getInnerGroupEP() {
+ return (GroupEditPart) getNote1EP().getParent();
+ }
+
+ protected GroupEditPart getOuterGroupEP() {
+ return (GroupEditPart) getNote2EP().getParent();
+ }
+
+ protected GroupEditPart groupShapes(List editparts) {
+ View childView = (View) ((IGraphicalEditPart) editparts.get(0))
+ .getModel();
+
+ GroupRequest request = new GroupRequest(ActionIds.ACTION_GROUP);
+ request.setEditParts(editparts);
+ Command cmd = ((IGraphicalEditPart) editparts.get(0)).getParent()
+ .getCommand(request);
+ assertTrue(cmd.canExecute());
+ getCommandStack().execute(cmd);
+ flushEventQueue();
+
+ EditPart groupEP = findEditPart(childView).getParent();
+ assertTrue(groupEP instanceof GroupEditPart);
+ return (GroupEditPart) groupEP;
+ }
+
+ protected Tool getSelectionToolFromPalette() {
+ PaletteViewer paletteViewer = getDiagramEditPart().getViewer()
+ .getEditDomain().getPaletteViewer();
+ ToolEntry selectionTool = paletteViewer.getPaletteRoot()
+ .getDefaultEntry();
+ paletteViewer.setActiveTool(selectionTool);
+ Tool tool = selectionTool.createTool();
+ tool.setEditDomain((EditDomain) getDiagramWorkbenchPart()
+ .getDiagramEditDomain());
+ return tool;
+ }
+
+ /**
+ * @return
+ */
+ protected IGraphicalEditPart findEditPart(View view) {
+ return (IGraphicalEditPart) getDiagramEditPart().getViewer()
+ .getEditPartRegistry().get(view);
+ }
+
+ protected MouseEvent createMouseEvent(int x, int y) {
+ Event e = new Event();
+
+ e.widget = getDiagramEditPart().getViewer().getControl();
+ ;
+ e.display = e.widget.getDisplay();
+ e.button = 1; // left button
+ e.x = x;
+ e.y = y;
+
+ return new MouseEvent(e);
+ }
+
+ protected MouseEvent createRightMouseEvent(int x, int y) {
+ Event e = new Event();
+
+ e.widget = getDiagramEditPart().getViewer().getControl();
+ ;
+ e.display = e.widget.getDisplay();
+ e.button = 3; // right button
+ e.x = x;
+ e.y = y;
+
+ return new MouseEvent(e);
+ }
+
+ protected Rectangle getAbsoluteBounds(IGraphicalEditPart editpart) {
+ Rectangle bounds = editpart.getFigure().getBounds().getCopy();
+ editpart.getFigure().translateToAbsolute(bounds);
+ return bounds;
+ }
+
+ public void testGroupCommandAndUndoRedo()
+ throws Exception {
+
+ setupShapes();
+
+ // Group note1 and geoshape1 and test undo/redo of the action.
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+
+ GroupEditPart group1EP = groupShapes(shapes);
+
+ assertEquals(3, getContainerEP().getChildren().size());
+ assertEquals(group1EP, getGeoshape1EP().getParent());
+ assertEquals(group1EP.getParent(), getContainerEP());
+ assertEquals(2, group1EP.getChildren().size());
+ assertEquals(getAbsoluteBounds(group1EP), getAbsoluteBounds(
+ getNote1EP()).union(getAbsoluteBounds(getGeoshape1EP())));
+
+ assertTrue(getCommandStack().canUndo());
+ getCommandStack().undo();
+
+ assertEquals(getContainerEP(), getNote1EP().getParent());
+ assertEquals(getGeoshape1EP().getParent(), getContainerEP());
+ assertEquals(4, getContainerEP().getChildren().size());
+
+ assertTrue(getCommandStack().canRedo());
+ getCommandStack().redo();
+
+ group1EP = (GroupEditPart) getNote1EP().getParent();
+ assertEquals(group1EP, getGeoshape1EP().getParent());
+ assertEquals(group1EP.getParent(), getContainerEP());
+ assertEquals(2, group1EP.getChildren().size());
+ assertEquals(3, getContainerEP().getChildren().size());
+ assertEquals(getAbsoluteBounds(group1EP), getAbsoluteBounds(
+ getNote1EP()).union(getAbsoluteBounds(getGeoshape1EP())));
+
+ // Group group1 and note2 and test undo/redo of the action.
+
+ shapes.clear();
+ shapes.add(group1EP);
+ shapes.add(getNote2EP());
+
+ GroupEditPart group2EP = groupShapes(shapes);
+
+ group1EP = (GroupEditPart) getNote1EP().getParent();
+
+ assertEquals(group1EP, getGeoshape1EP().getParent());
+ assertEquals(group2EP, group1EP.getParent());
+ assertEquals(group2EP, getNote2EP().getParent());
+ assertEquals(getContainerEP(), group2EP.getParent());
+ assertEquals(2, group1EP.getChildren().size());
+ assertEquals(2, group2EP.getChildren().size());
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(getAbsoluteBounds(group2EP), getAbsoluteBounds(
+ getNote2EP()).union(getAbsoluteBounds(group1EP)));
+
+ assertTrue(getCommandStack().canUndo());
+ getCommandStack().undo();
+
+ group1EP = (GroupEditPart) getNote1EP().getParent();
+ assertEquals(getContainerEP(), group1EP.getParent());
+ assertEquals(getContainerEP(), getNote2EP().getParent());
+ assertEquals(3, getContainerEP().getChildren().size());
+
+ assertTrue(getCommandStack().canRedo());
+ getCommandStack().redo();
+
+ group1EP = (GroupEditPart) getNote1EP().getParent();
+ group2EP = (GroupEditPart) getNote2EP().getParent();
+ assertEquals(group2EP, group1EP.getParent());
+ assertEquals(getContainerEP(), group2EP.getParent());
+ assertEquals(2, group1EP.getChildren().size());
+ assertEquals(2, group2EP.getChildren().size());
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(getAbsoluteBounds(group2EP), getAbsoluteBounds(
+ getNote2EP()).union(getAbsoluteBounds(group1EP)));
+ }
+
+ public void testUngroupCommandAndUndoRedo()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ // Ungroup the top-level group.
+ Request request = new Request(ActionIds.ACTION_UNGROUP);
+ Command cmd = getOuterGroupEP().getCommand(request);
+ assertTrue(cmd.canExecute());
+ getCommandStack().execute(cmd);
+ // flushEventQueue();
+
+ assertEquals(3, getContainerEP().getChildren().size());
+ assertEquals(getContainerEP(), getInnerGroupEP().getParent());
+ assertEquals(getContainerEP(), getNote2EP().getParent());
+
+ // Undo the ungroup of the top-level group.
+ assertTrue(getCommandStack().canUndo());
+ getCommandStack().undo();
+
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(getOuterGroupEP(), getInnerGroupEP().getParent());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+
+ // Redo the ungroup of the top-level group.
+ assertTrue(getCommandStack().canRedo());
+ getCommandStack().redo();
+ // flushEventQueue();
+
+ assertEquals(3, getContainerEP().getChildren().size());
+ assertEquals(getContainerEP(), getInnerGroupEP().getParent());
+ assertEquals(getContainerEP(), getNote2EP().getParent());
+ }
+
+ public void testGroupIsSelectedAfterGroupAction()
+ throws Exception {
+
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+
+ GroupAction action = new GroupAction(getWorkbenchPage());
+ getWorkbenchPage().activate(getDiagramWorkbenchPart());
+ action.init();
+
+ EditPartViewer viewer = getDiagramWorkbenchPart()
+ .getDiagramGraphicalViewer();
+ viewer.deselectAll();
+ viewer.setSelection(new StructuredSelection(shapes));
+
+ action.refresh();
+ assertTrue(action.isEnabled());
+ action.run();
+ action.dispose();
+
+ flushEventQueue();
+
+ assertEquals(1, ((StructuredSelection) viewer.getSelection()).size());
+ assertTrue(((StructuredSelection) viewer.getSelection())
+ .getFirstElement() instanceof GroupEditPart);
+ }
+
+ public void testGroupActionEnablement()
+ throws Exception {
+ setupShapes();
+
+ GroupAction action = new GroupAction(getWorkbenchPage());
+ getWorkbenchPage().activate(getDiagramWorkbenchPart());
+ action.init();
+
+ EditPartViewer viewer = getDiagramWorkbenchPart()
+ .getDiagramGraphicalViewer();
+ viewer.deselectAll();
+
+ // should be enabled when connections are included in the selection
+ viewer.setSelection(new StructuredSelection(getDiagramEditPart()
+ .getPrimaryEditParts()));
+ action.refresh();
+ assertTrue(action.isEnabled());
+
+ // should be disabled when only one shape is selected
+ viewer.setSelection(new StructuredSelection(getNote1EP()));
+ action.refresh();
+ assertFalse(action.isEnabled());
+
+ // should be enabled when connections are included in the selection
+ viewer.setSelection(new StructuredSelection(getDiagramEditPart()
+ .getPrimaryEditParts()));
+ action.refresh();
+ assertTrue(action.isEnabled());
+
+ // should be disabled when only connections are selected
+ viewer.setSelection(new StructuredSelection(getDiagramEditPart()
+ .getConnections()));
+ action.refresh();
+ assertFalse(action.isEnabled());
+
+ // should be enabled on groups
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+ GroupEditPart groupEP = groupShapes(shapes);
+ shapes.clear();
+ shapes.add(groupEP);
+ shapes.add(getNote2EP());
+ viewer.setSelection(new StructuredSelection(shapes));
+ action.refresh();
+ assertTrue(action.isEnabled());
+
+ // should be disabled on uneditable diagrams
+ getContainerEP().disableEditMode();
+ action.refresh();
+ assertFalse(action.isEnabled());
+ }
+
+ public void testUngroupActionEnablement()
+ throws Exception {
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+ GroupEditPart group1EP = groupShapes(shapes);
+
+ shapes.clear();
+ shapes.add(getNote2EP());
+ shapes.add(getGeoshape2EP());
+ GroupEditPart group2EP = groupShapes(shapes);
+
+ UngroupAction action = new UngroupAction(getWorkbenchPage());
+ getWorkbenchPage().activate(getDiagramWorkbenchPart());
+ action.init();
+
+ EditPartViewer viewer = getDiagramWorkbenchPart()
+ .getDiagramGraphicalViewer();
+ viewer.deselectAll();
+
+ // should be enabled when one group is selected
+ viewer.setSelection(new StructuredSelection(getInnerGroupEP()));
+ action.refresh();
+ assertTrue(action.isEnabled());
+
+ // should be enabled when multiple groups are selected
+ List groups = new LinkedList();
+ groups.add(group1EP);
+ groups.add(group2EP);
+ viewer.setSelection(new StructuredSelection(groups));
+ action.refresh();
+ assertTrue(action.isEnabled());
+ }
+
+ public void testSelectGroupWithClickAndDrag()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ PaletteViewer paletteViewer = viewer.getEditDomain().getPaletteViewer();
+
+ ToolEntry selectionTool = paletteViewer.getPaletteRoot()
+ .getDefaultEntry();
+ paletteViewer.setActiveTool(selectionTool);
+ Tool tool = selectionTool.createTool();
+ tool.setEditDomain((EditDomain) getDiagramWorkbenchPart()
+ .getDiagramEditDomain());
+
+ // draw rubber band around all the shapes
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+ tool.mouseDown(createMouseEvent(0, 0), viewer);
+ tool.mouseDrag(createMouseEvent(200, 200), viewer);
+ tool.mouseUp(createMouseEvent(200, 200), viewer);
+ tool.deactivate();
+
+ // size should be 6: 1 group, 1 shape, 4 connections
+ assertEquals(6, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getOuterGroupEP()));
+ }
+
+ public void testSelectGroupWithRightClick()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Tool tool = getSelectionToolFromPalette();
+
+ // click on a shape in the outer group and the outer group should be
+ // selected
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+ Point point = getAbsoluteBounds(getNote2EP()).getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getOuterGroupEP()));
+
+ // right-click on the same shape a second time and the group should
+ // still be
+ // selected
+ tool.mouseDown(createRightMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createRightMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getOuterGroupEP()));
+ }
+
+ public void testSelectShapesAndGroupsWithClick()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Tool tool = getSelectionToolFromPalette();
+
+ // click on a shape in the outer group and the outer group should be
+ // selected
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+ Point point = getAbsoluteBounds(getNote2EP()).getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getOuterGroupEP()));
+
+ // click on the same shape a second time and the shape should be
+ // selected
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getNote2EP()));
+
+ // right-click on the same shape and it should remain selected
+ tool.mouseDown(createRightMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createRightMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getNote2EP()));
+
+ // click on a shape not in the group and that shape itself should be
+ // selected
+ viewer.getSelectionManager().deselectAll();
+ point = getAbsoluteBounds(getGeoshape2EP()).getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getGeoshape2EP()));
+
+ // click on an area of blank space in a group and nothing should be
+ // selected
+ viewer.getSelectionManager().deselectAll();
+ tool.mouseDown(createMouseEvent(30, 75), viewer);
+ tool.mouseUp(createMouseEvent(30, 75), viewer);
+
+ assertEquals(0, viewer.getSelectedEditParts().size());
+
+ // click on a shape in the inner group and the outer group should be
+ // selected
+ viewer.getSelectionManager().deselectAll();
+ point = getAbsoluteBounds(getNote1EP()).getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getOuterGroupEP()));
+
+ // click on the same shape a second time and the inner group should be
+ // selected
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getInnerGroupEP()));
+
+ // click on the same shape a third time and the shape itself should be
+ // selected
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertTrue(viewer.getSelectedEditParts().contains(getNote1EP()));
+
+ tool.deactivate();
+ }
+
+ /**
+ * This ensure that when a group is created you can select a connection that
+ * exists between shapes in the group. The issue was that the connection
+ * editpart was not active.
+ *
+ * This fails because of GEF Bugzilla 174085.
+ *
+ * @throws Exception
+ */
+ public void testSelectConnectionInGroupWithClick()
+ throws Exception {
+
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+ GroupEditPart groupEP = groupShapes(shapes);
+
+ ConnectionEditPart connectionEP = (ConnectionEditPart) getNote1EP()
+ .getSourceConnections().get(0);
+
+ Tool tool = getSelectionToolFromPalette();
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+
+ Point point = getAbsoluteBounds(connectionEP).getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ assertEquals(1, viewer.getSelectedEditParts().size());
+ assertEquals(connectionEP, viewer.getSelectedEditParts().get(0));
+ assertTrue(connectionEP.isActive());
+ assertTrue(connectionEP.getSource().isActive());
+ assertEquals(groupEP, connectionEP.getSource().getParent());
+ assertTrue(connectionEP.getTarget().isActive());
+ assertEquals(groupEP, connectionEP.getTarget().getParent());
+
+ tool.deactivate();
+ }
+
+ public void testMoveGroup()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Tool tool = getSelectionToolFromPalette();
+
+ System.out.println(getInnerGroupEP().getFigure().getBounds());
+ System.out.println(getAbsoluteBounds(getInnerGroupEP()));
+ Rectangle origGroupBounds = getAbsoluteBounds(getInnerGroupEP());
+ Rectangle origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ Rectangle origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ Point offset = new Point(25, 25);
+
+ // Click and drag the group in one gesture.
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+ Point point = origNote1Bounds.getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ point.translate(offset);
+ tool.mouseDrag(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+ tool.deactivate();
+ flushEventQueue();
+ Thread.sleep(5000);
+
+ // Cannot test the exact bounds because I can't figure out what the
+ // exact bounds should be (maybe there are rounding issues?) so the
+ // tests here will have to do.
+ Dimension resultingOffset = origGroupBounds.getLocation()
+ .getDifference(getAbsoluteBounds(getInnerGroupEP()).getLocation());
+ assertTrue(resultingOffset.height != 0 && resultingOffset.width != 0);
+ assertEquals(resultingOffset, origNote1Bounds.getLocation()
+ .getDifference(getAbsoluteBounds(getNote1EP()).getLocation()));
+ assertEquals(resultingOffset, origGeoshape1Bounds.getLocation()
+ .getDifference(getAbsoluteBounds(getGeoshape1EP()).getLocation()));
+
+ // Now select the group first and then click over a shape and drag. This
+ // should move the group.
+ origGroupBounds = getAbsoluteBounds(getInnerGroupEP());
+ origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+ point = origNote1Bounds.getCenter();
+ offset = new Point(-25, -25);
+
+ viewer.getSelectionManager().deselectAll();
+ viewer.select(getInnerGroupEP());
+ tool.activate();
+
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ point.translate(offset);
+ tool.mouseDrag(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+ tool.deactivate();
+
+ flushEventQueue();
+
+ // Cannot test the exact bounds because I can't figure out what the
+ // exact bounds should be (maybe there are rounding issues?) so the
+ // tests here will have to do.
+ resultingOffset = origGroupBounds.getLocation().getDifference(
+ getAbsoluteBounds(getInnerGroupEP()).getLocation());
+ assertTrue(resultingOffset.height != 0 && resultingOffset.width != 0);
+
+ resultingOffset = origNote1Bounds.getLocation().getDifference(
+ getAbsoluteBounds(getNote1EP()).getLocation());
+ assertTrue(resultingOffset.height != 0 && resultingOffset.width != 0);
+
+ resultingOffset = origGeoshape1Bounds.getLocation().getDifference(
+ getAbsoluteBounds(getGeoshape1EP()).getLocation());
+ assertTrue(resultingOffset.height != 0 && resultingOffset.width != 0);
+
+ // Confirm sizes are still the same.
+ assertEquals(origGroupBounds.getSize(), getAbsoluteBounds(
+ getInnerGroupEP()).getSize());
+ assertEquals(origNote1Bounds.getSize(), getAbsoluteBounds(getNote1EP())
+ .getSize());
+ assertEquals(origGeoshape1Bounds.getSize(), getAbsoluteBounds(
+ getGeoshape1EP()).getSize());
+ }
+
+ public void testMoveShapeInGroup()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Tool tool = getSelectionToolFromPalette();
+
+ Rectangle origGroupBounds = getAbsoluteBounds(getInnerGroupEP());
+ Rectangle origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ Rectangle origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ Point offset = new Point(25, 25);
+
+ // Move geoshape1. Click three times -- first select the outer group,
+ // then select the inner group, then select geoshape1.
+ EditPartViewer viewer = getDiagramEditPart().getViewer();
+ viewer.getSelectionManager().deselectAll();
+ tool.activate();
+ Point point = origGeoshape1Bounds.getCenter();
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+
+ // Now click and drag geoshape1 to move it.
+ tool.mouseDown(createMouseEvent(point.x, point.y), viewer);
+ point.translate(offset);
+ tool.mouseDrag(createMouseEvent(point.x, point.y), viewer);
+ tool.mouseUp(createMouseEvent(point.x, point.y), viewer);
+ tool.deactivate();
+ flushEventQueue();
+
+ // Confirm geoshape1 was not removed from the group.
+ assertEquals(2, getInnerGroupEP().getChildren().size());
+
+ // geoshape1 should have moved.
+ Dimension resultingOffset = origGeoshape1Bounds.getLocation()
+ .getDifference(getAbsoluteBounds(getGeoshape1EP()).getLocation());
+ assertTrue(resultingOffset.height != 0 && resultingOffset.width != 0);
+ assertEquals(origGeoshape1Bounds.getSize(), getAbsoluteBounds(
+ getGeoshape1EP()).getSize());
+
+ // note1 should remain the same.
+ assertEquals(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+
+ // The group location should not have changed but the size should have
+ // grown.
+ assertEquals(origGroupBounds.getLocation(), getAbsoluteBounds(
+ getInnerGroupEP()).getLocation());
+ assertNotSame(origGroupBounds.getSize(), getAbsoluteBounds(
+ getInnerGroupEP()).getSize());
+
+ }
+
+ public void testUngroupShapesMaintainsShapeLocations()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ // Ungroup the inner group.
+
+ // First cache the bounds in absolute coordinates of one of the figures.
+ Rectangle origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ // Perform the ungroup.
+ Request request = new Request(ActionIds.ACTION_UNGROUP);
+ Command cmd = getInnerGroupEP().getCommand(request);
+ assertTrue(cmd.canExecute());
+ getCommandStack().execute(cmd);
+ flushEventQueue();
+
+ // Test that the bounds in absolute have not changed.
+ assertEquals(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+
+ // Ungroup the outer group.
+
+ // First cache the bounds in absolute coordinates of one of the figures.
+ Rectangle origNote2Bounds = getAbsoluteBounds(getNote2EP());
+
+ // Perform the ungroup.
+ request = new Request(ActionIds.ACTION_UNGROUP);
+ cmd = getInnerGroupEP().getCommand(request);
+ assertTrue(cmd.canExecute());
+ getCommandStack().execute(cmd);
+ flushEventQueue();
+
+ // Test that the bounds in absolute have not changed.
+ assertEquals(origNote2Bounds, getAbsoluteBounds(getNote2EP()));
+ }
+
+ public void testDeleteShapeInGroup()
+ throws Exception {
+
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+ shapes.add(getGeoshape2EP());
+
+ GroupEditPart groupEP = groupShapes(shapes);
+
+ shapes.clear();
+ shapes.add(groupEP);
+ shapes.add(getNote2EP());
+
+ groupShapes(shapes);
+
+ // Inner group has 3 shapes, outer group has inner group and 1 shape.
+ assertEquals(1, getContainerEP().getChildren().size());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+ assertEquals(3, getInnerGroupEP().getChildren().size());
+
+ Request request = new GroupRequest(RequestConstants.REQ_DELETE);
+
+ // Delete one shape from the inner group.
+ getCommandStack().execute(getGeoshape1EP().getCommand(request));
+
+ // Inner group should now have 2 shapes.
+ assertEquals(2, getInnerGroupEP().getChildren().size());
+
+ // Delete another shape from the inner group.
+ getCommandStack().execute(getNote1EP().getCommand(request));
+
+ // Inner group should not exist anymore.
+ assertEquals(getOuterGroupEP(), getGeoshape2EP().getParent());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+
+ // Now try undo.
+ getCommandStack().undo();
+ getCommandStack().undo();
+
+ // Inner group has 3 shapes, outer group has inner group and 1 shape.
+ assertEquals(1, getContainerEP().getChildren().size());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+ assertEquals(3, getInnerGroupEP().getChildren().size());
+
+ }
+
+ public void testCannotResizeGroup()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ ChangeBoundsRequest request = new ChangeBoundsRequest(
+ RequestConstants.REQ_RESIZE);
+ request.setResizeDirection(PositionConstants.SOUTH);
+ request.setEditParts(getOuterGroupEP());
+ request.setSizeDelta(new Dimension(0, 100));
+
+ Command cmd = getOuterGroupEP().getCommand(request);
+ assertTrue(cmd == null || !cmd.canExecute());
+ }
+
+ public void testResizeShapeInGroup()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Rectangle origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ Rectangle origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ // Increase note1's size by 10 on each side.
+ ChangeBoundsRequest request = new ChangeBoundsRequest(
+ RequestConstants.REQ_RESIZE);
+ request.setResizeDirection(PositionConstants.NORTH_EAST);
+ request.setEditParts(getNote1EP());
+ request.setSizeDelta(new Dimension(10, 10));
+
+ getNote1EP().getCommand(request).execute();
+
+ assertNotSame(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ request.setResizeDirection(PositionConstants.SOUTH_WEST);
+ getNote1EP().getCommand(request).execute();
+
+ assertEquals(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ // Increase geoshape1's size by 10 on each side.
+ origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ request.setResizeDirection(PositionConstants.SOUTH_EAST);
+ request.setEditParts(getGeoshape1EP());
+
+ getGeoshape1EP().getCommand(request).execute();
+
+ assertNotSame(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+ assertEquals(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ request.setResizeDirection(PositionConstants.NORTH_WEST);
+ getGeoshape1EP().getCommand(request).execute();
+
+ assertEquals(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ // Decrease note1's size by 10 on each side.
+ origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ origGeoshape1Bounds = getAbsoluteBounds(getGeoshape1EP());
+
+ request.setResizeDirection(PositionConstants.NORTH_EAST);
+ request.setEditParts(getNote1EP());
+ request.setSizeDelta(new Dimension(-10, -10));
+
+ getNote1EP().getCommand(request).execute();
+
+ assertNotSame(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ request.setResizeDirection(PositionConstants.SOUTH_WEST);
+ getNote1EP().getCommand(request).execute();
+
+ assertEquals(origGeoshape1Bounds, getAbsoluteBounds(getGeoshape1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ // Decrease geoshape1's size by 10 on each side.
+ origNote1Bounds = getAbsoluteBounds(getNote1EP());
+ origGeoshape1Bounds = getAbsoluteBounds(getNote1EP());
+
+ request.setResizeDirection(PositionConstants.SOUTH_EAST);
+ request.setEditParts(getGeoshape1EP());
+
+ getGeoshape1EP().getCommand(request).execute();
+
+ assertNotSame(origGeoshape1Bounds, getGeoshape1EP().getFigure()
+ .getBounds());
+ assertEquals(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+
+ request.setResizeDirection(PositionConstants.NORTH_WEST);
+ getGeoshape1EP().getCommand(request).execute();
+
+ assertEquals(origNote1Bounds, getAbsoluteBounds(getNote1EP()));
+ assertEquals(getAbsoluteBounds(getNote1EP()).union(
+ getAbsoluteBounds(getGeoshape1EP())),
+ getAbsoluteBounds(getInnerGroupEP()));
+ }
+
+ public void testDeleteGroup()
+ throws Exception {
+
+ setupShapesAndGroups();
+
+ Request request = new GroupRequest(RequestConstants.REQ_DELETE);
+ getCommandStack().execute(getOuterGroupEP().getCommand(request));
+
+ assertEquals(1, getContainerEP().getChildren().size());
+
+ getCommandStack().undo();
+
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(2, getOuterGroupEP().getChildren().size());
+ assertEquals(2, getInnerGroupEP().getChildren().size());
+
+ }
+
+ public void testSelectActions()
+ throws Exception {
+ setupShapesAndGroups();
+
+ // test select all
+ getContainerEP().getViewer().setSelection(
+ new StructuredSelection(getContainerEP()));
+
+ SelectAllAction selectAction = SelectAllAction
+ .createSelectAllAction(getWorkbenchPage());
+
+ testAction(selectAction, new ITestActionCallback() {
+
+ public void onRunExecution() {
+
+ List selectedParts = getContainerEP().getViewer()
+ .getSelectedEditParts();
+
+ // 2 shapes and 4 connectors
+ assertEquals(6, selectedParts.size());
+ assertTrue(selectedParts.contains(getOuterGroupEP()));
+ assertTrue(selectedParts.contains(getNote2EP()
+ .getSourceConnections().get(0)));
+ assertFalse(selectedParts.contains(getNote1EP()));
+
+ }
+ });
+
+ // test select all shapes
+ getContainerEP().getViewer().deselectAll();
+ getContainerEP().getViewer().setSelection(
+ new StructuredSelection(getContainerEP()));
+
+ selectAction = SelectAllAction
+ .createSelectAllShapesAction(getWorkbenchPage());
+
+ testAction(selectAction, new ITestActionCallback() {
+
+ public void onRunExecution() {
+
+ List selectedParts = getContainerEP().getViewer()
+ .getSelectedEditParts();
+
+ // 2 shapes
+ assertEquals(2, selectedParts.size());
+ assertTrue(selectedParts.contains(getOuterGroupEP()));
+ assertTrue(selectedParts.contains(getGeoshape2EP()));
+
+ }
+ });
+
+ // test select all connections
+ getContainerEP().getViewer().deselectAll();
+ getContainerEP().getViewer().setSelection(
+ new StructuredSelection(getContainerEP()));
+
+ selectAction = SelectAllAction
+ .createSelectAllConnectionsAction(getWorkbenchPage());
+
+ testAction(selectAction, new ITestActionCallback() {
+
+ public void onRunExecution() {
+
+ List selectedParts = getContainerEP().getViewer()
+ .getSelectedEditParts();
+
+ // 4 connectors
+ assertEquals(4, selectedParts.size());
+ assertTrue(selectedParts.contains(getNote2EP()
+ .getSourceConnections().get(0)));
+ }
+ });
+ }
+
+}
diff --git a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupsInCompartmentTests.java b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupsInCompartmentTests.java
new file mode 100644
index 0000000..45cfbcc
--- /dev/null
+++ b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/logic/GroupsInCompartmentTests.java
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ****************************************************************************/
+
+package org.eclipse.gmf.tests.runtime.diagram.ui.logic;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gmf.examples.runtime.diagram.logic.internal.editparts.CircuitEditPart;
+import org.eclipse.gmf.examples.runtime.diagram.logic.internal.providers.LogicConstants;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.geoshapes.internal.providers.GeoshapeType;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.notation.View;
+
+/**
+ * Repeat all the same tests in <code>GroupTests</code> but within a
+ * compartment.
+ *
+ * @author crevells
+ */
+public class GroupsInCompartmentTests
+ extends GroupTests {
+
+ public static Test suite() {
+ TestSuite s = new TestSuite(GroupsInCompartmentTests.class);
+ return s;
+ }
+
+ private static IElementType CIRCUIT_TYPE = ElementTypeRegistry
+ .getInstance().getType("logic.circuit"); //$NON-NLS-1$
+
+ private IGraphicalEditPart logicCompartmentEP;
+
+ protected IGraphicalEditPart getContainerEP() {
+ return logicCompartmentEP;
+ }
+
+ protected void setTestFixture() {
+ testFixture = new GroupTestFixture() {
+
+ protected void createShapesAndConnectors()
+ throws Exception {
+
+ // create the circuit that is the container
+ IElementType typeCircuit = ElementTypeRegistry.getInstance()
+ .getType("logic.circuit"); //$NON-NLS-1$
+ CircuitEditPart circuitEP = (CircuitEditPart) getFixture()
+ .createShapeUsingTool(typeCircuit, new Point(5, 5),
+ new Dimension(300, 300));
+ logicCompartmentEP = circuitEP
+ .getChildBySemanticHint(LogicConstants.LOGIC_SHAPE_COMPARTMENT);
+ }
+ };
+ }
+
+ /**
+ * Create LEDs instead of Notes to test for canonical issues.
+ */
+ protected void setupShapes() {
+
+ ShapeEditPart note1EP = getFixture().createShapeUsingTool(CIRCUIT_TYPE,
+ new Point(10, 10), getContainerEP(), new Dimension(50, 50));
+
+ ShapeEditPart note2EP = getFixture().createShapeUsingTool(CIRCUIT_TYPE,
+ new Point(100, 10), getContainerEP(), new Dimension(50, 50));
+
+ ShapeEditPart geoshape1EP = getFixture().createShapeUsingTool(
+ GeoshapeType.CYLINDER, new Point(10, 100), getContainerEP(),
+ new Dimension(50, 50));
+
+ ShapeEditPart geoshape2EP = getFixture().createShapeUsingTool(
+ GeoshapeType.DIAMOND, new Point(100, 100), getContainerEP(),
+ new Dimension(50, 50));
+
+ flushEventQueue();
+
+ // Cache the views so we can find the editparts again later.
+ note1View = (View) note1EP.getModel();
+ note2View = (View) note2EP.getModel();
+ geoshape1View = (View) geoshape1EP.getModel();
+ geoshape2View = (View) geoshape2EP.getModel();
+
+ // Create some connections just to make things more complicated.
+ getFixture().createConnectorUsingTool(note1EP, geoshape1EP,
+ GeoshapeType.LINE);
+ getFixture().createConnectorUsingTool(note2EP, geoshape1EP,
+ GeoshapeType.LINE);
+ getFixture().createConnectorUsingTool(note2EP, geoshape2EP,
+ GeoshapeType.LINE);
+ getFixture().createConnectorUsingTool(geoshape1EP, geoshape2EP,
+ GeoshapeType.LINE);
+
+ flushEventQueue();
+ }
+
+ public void testRefreshCanonicalDoesNotCreateDoubles()
+ throws Exception {
+ setupShapesAndGroups();
+
+ assertEquals(2, getContainerEP().getChildren().size());
+
+ // trigger a canonical refresh
+ getFixture().createShapeUsingTool(CIRCUIT_TYPE, new Point(10, 10),
+ getContainerEP(), new Dimension(50, 50));
+ flushEventQueue();
+
+ assertEquals(3, getContainerEP().getChildren().size());
+ }
+
+ public void testDeleteShapeInGroupDoesNotReappear()
+ throws Exception {
+
+ setupShapes();
+
+ List shapes = new LinkedList();
+ shapes.add(getNote1EP());
+ shapes.add(getGeoshape1EP());
+ shapes.add(getGeoshape2EP());
+
+ GroupEditPart groupEP = groupShapes(shapes);
+
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(3, groupEP.getChildren().size());
+
+ Request request = new GroupRequest(RequestConstants.REQ_DELETE);
+
+ // Delete one shape from the inner group.
+ getCommandStack().execute(getNote1EP().getCommand(request));
+
+ assertEquals(2, getContainerEP().getChildren().size());
+ assertEquals(2, groupEP.getChildren().size());
+
+ // trigger a canonical refresh
+ getFixture().createShapeUsingTool(CIRCUIT_TYPE, new Point(10, 10),
+ getContainerEP(), new Dimension(50, 50));
+ flushEventQueue();
+
+ assertEquals(3, getContainerEP().getChildren().size());
+ assertEquals(2, groupEP.getChildren().size());
+
+ }
+
+}
diff --git a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/util/AbstractPresentationTestFixture.java b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/util/AbstractPresentationTestFixture.java
index b6cf997..bf2cc44 100644
--- a/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/util/AbstractPresentationTestFixture.java
+++ b/org.eclipse.gmf.tests.runtime.diagram.ui/src/org/eclipse/gmf/tests/runtime/diagram/ui/util/AbstractPresentationTestFixture.java
@@ -24,6 +24,7 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
+import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
@@ -398,60 +399,78 @@
}
}
- /**
- * Creates a new shape using the request created by the
- * <code>CreationTool</code>.
- *
- * @param elementType
- * the type of the shape/element to be created
- * @param location
- * the location for the new shape
- * @return the new shape's editpart
- */
- public ShapeEditPart createShapeUsingTool(IElementType elementType,
- Point location, IGraphicalEditPart containerEP) {
+ /**
+ * Creates a new shape using the request created by the
+ * <code>CreationTool</code>.
+ *
+ * @param elementType
+ * the type of the shape/element to be created
+ * @param location
+ * the location for the new shape
+ * @return the new shape's editpart
+ */
+ public ShapeEditPart createShapeUsingTool(IElementType elementType,
+ Point location, IGraphicalEditPart containerEP) {
+ return createShapeUsingTool(elementType, location, containerEP, null);
+ }
+
+ /**
+ * Creates a new shape using the request created by the
+ * <code>CreationTool</code>.
+ *
+ * @param elementType
+ * the type of the shape/element to be created
+ * @param location
+ * the location for the new shape
+ * @param size
+ * the initial size of the new shape
+ * @return the new shape's editpart
+ */
+ public ShapeEditPart createShapeUsingTool(IElementType elementType,
+ Point location, IGraphicalEditPart containerEP, Dimension size) {
- CreateRequest request = getCreationRequest(elementType);
- request.setLocation(location);
- Command cmd = containerEP.getCommand(request);
+ CreateRequest request = getCreationRequest(elementType);
+ request.setLocation(location);
+ request.setSize(size);
+ Command cmd = containerEP.getCommand(request);
- int previousNumChildren = containerEP.getChildren().size();
+ int previousNumChildren = containerEP.getChildren().size();
- getCommandStack().execute(cmd);
- assertEquals(previousNumChildren + 1, containerEP.getChildren().size());
+ getCommandStack().execute(cmd);
+ assertEquals(previousNumChildren + 1, containerEP.getChildren().size());
- Object newView = ((IAdaptable) ((List) request.getNewObject()).get(0)).getAdapter(View.class);
- assertNotNull(newView);
- assertTrue(!ViewUtil.isTransient((View)newView));
-
- EObject element = ((View)newView).getElement();
-
- getCommandStack().undo();
- assertEquals(previousNumChildren, containerEP.getChildren().size());
+ Object newView = ((IAdaptable) ((List) request.getNewObject()).get(0)).getAdapter(View.class);
+ assertNotNull(newView);
+ assertTrue(!ViewUtil.isTransient((View)newView));
+
+ EObject element = ((View)newView).getElement();
+
+ getCommandStack().undo();
+ assertEquals(previousNumChildren, containerEP.getChildren().size());
- getCommandStack().redo();
- assertEquals(previousNumChildren + 1, containerEP.getChildren().size());
+ getCommandStack().redo();
+ assertEquals(previousNumChildren + 1, containerEP.getChildren().size());
- IGraphicalEditPart newShape = null;
- if (element != null) {
- List children = containerEP.getChildren();
- ListIterator li = children.listIterator();
- while (li.hasNext()) {
- IGraphicalEditPart gep = (IGraphicalEditPart)li.next();
- if (gep.getNotationView().getElement().equals(element)) {
- newShape = gep;
- }
- }
- }
- else {
- newShape = (ShapeEditPart) getDiagramEditPart()
- .getViewer().getEditPartRegistry().get(newView);
- assertNotNull(newShape);
- }
-
- assertTrue(newShape != null && newShape instanceof ShapeEditPart);
- return (ShapeEditPart)newShape;
- }
+ IGraphicalEditPart newShape = null;
+ if (element != null) {
+ List children = containerEP.getChildren();
+ ListIterator li = children.listIterator();
+ while (li.hasNext()) {
+ IGraphicalEditPart gep = (IGraphicalEditPart)li.next();
+ if (gep.getNotationView() != null && element.equals(gep.getNotationView().getElement())) {
+ newShape = gep;
+ }
+ }
+ }
+ else {
+ newShape = (ShapeEditPart) getDiagramEditPart()
+ .getViewer().getEditPartRegistry().get(newView);
+ assertNotNull(newShape);
+ }
+
+ assertTrue(newShape != null && newShape instanceof ShapeEditPart);
+ return (ShapeEditPart)newShape;
+ }
/**
* Given an <code>IElementType</code>, gets the creation request that can be used to
@@ -483,22 +502,43 @@
return request;
}
- /**
- * Creates a new shape using the request created by the
- * <code>CreationTool</code>.
- *
- * @param elementType
- * the type of the shape/element to be created
- * @param location
- * the location for the new shape
- * @return the new shape's editpart
- */
- public ShapeEditPart createShapeUsingTool(IElementType elementType,
- Point location) {
+ /**
+ * Creates a new shape using the request created by the
+ * <code>CreationTool</code>.
+ *
+ * @param elementType
+ * the type of the shape/element to be created
+ * @param location
+ * the location for the new shape
+ * @return the new shape's editpart
+ */
+ public ShapeEditPart createShapeUsingTool(IElementType elementType,
+ Point location) {
- return createShapeUsingTool(elementType, location, getDiagramEditPart());
+ return createShapeUsingTool(elementType, location, getDiagramEditPart());
- }
+ }
+
+ /**
+ * Creates a new shape using the request created by the
+ * <code>CreationTool</code>.
+ *
+ * @param elementType
+ * the type of the shape/element to be created
+ * @param location
+ * the location for the new shape
+ * @param size
+ * the initial size of the new shape
+ * @return the new shape's editpart
+ */
+ public ShapeEditPart createShapeUsingTool(IElementType elementType,
+ Point location, Dimension size) {
+
+ ShapeEditPart shapeEP = createShapeUsingTool(elementType, location, getDiagramEditPart(), size);
+
+ return shapeEP;
+
+ }
/**
* Creates a new connector using the request created by the