Skip to content

Commit

Permalink
Delete object and move child objects to parent
Browse files Browse the repository at this point in the history
  • Loading branch information
Phillipus committed Oct 21, 2024
1 parent 89ac466 commit 7ad0615
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 27 deletions.
6 changes: 6 additions & 0 deletions com.archimatetool.editor/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,12 @@
id="com.archimatetool.editor.action.deleteFromModel"
name="%command.name.20">
</command>
<command
categoryId="org.eclipse.ui.category.edit"
description="Delete from View keeping children"
id="com.archimatetool.editor.action.deleteContainer"
name="Delete from View (keep children)">
</command>
<command
categoryId="com.archimatetool.editor.category"
description="%command.description.21"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ private MenuManager createEditMenu() {
menu.add(fActionCopy);
menu.add(fActionPaste);
menu.add(fActionPasteSpecial);
menu.add(new Separator());
menu.add(fActionDelete);
menu.add(new Separator(IWorkbenchActionConstants.CUT_EXT));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import com.archimatetool.editor.diagram.actions.CopyAction;
import com.archimatetool.editor.diagram.actions.CutAction;
import com.archimatetool.editor.diagram.actions.DefaultEditPartSizeAction;
import com.archimatetool.editor.diagram.actions.DeleteContainerAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageToClipboardAction;
import com.archimatetool.editor.diagram.actions.FillColorAction;
Expand Down Expand Up @@ -700,6 +701,11 @@ protected void createActions(GraphicalViewer viewer) {
action.setToolTipText(action.getText());
getUpdateCommandStackActions().add((UpdateAction)action);

// Delete Container
action = new DeleteContainerAction(this);
registry.registerAction(action);
getSelectionActions().add(action.getId());

// Paste
PasteAction pasteAction = new PasteAction(this, viewer);
registry.registerAction(pasteAction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.archimatetool.editor.diagram.actions.LineWidthAction;
import com.archimatetool.editor.diagram.actions.ConnectionRouterAction;
import com.archimatetool.editor.diagram.actions.DefaultEditPartSizeAction;
import com.archimatetool.editor.diagram.actions.DeleteContainerAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageToClipboardAction;
import com.archimatetool.editor.diagram.actions.FillColorAction;
Expand Down Expand Up @@ -75,7 +76,9 @@ public abstract class AbstractDiagramEditorActionBarContributor
protected static final String GROUP_TOOLBAR_END = "group_toolbarEnd"; //$NON-NLS-1$
protected static final String GROUP_POSITION = "group_position"; //$NON-NLS-1$
protected static final String GROUP_CONNECTIONS = "group_connections"; //$NON-NLS-1$

protected static final String GROUP_EDIT_DELETE_MENU = "editDeleteMenuGroup"; //$NON-NLS-1$


@Override
protected void buildActions() {
// Zoom in
Expand Down Expand Up @@ -201,6 +204,12 @@ protected void buildActions() {

// Lock
addRetargetAction(new LabelRetargetAction(LockObjectAction.ID, Messages.AbstractDiagramEditorActionBarContributor_3));

// Delete Container
retargetAction = new RetargetAction(DeleteContainerAction.ID, DeleteContainerAction.TEXT);
retargetAction.setActionDefinitionId(DeleteContainerAction.ID); // key binding
retargetAction.setToolTipText(DeleteContainerAction.TOOLTIP_TEXT);
addRetargetAction(retargetAction);
}

@Override
Expand Down Expand Up @@ -331,6 +340,12 @@ protected IMenuManager contributeToEditMenu(IMenuManager menuManager) {
textAlignmentMenu.add(getAction(TextAlignmentAction.ACTION_CENTER_ID));
textAlignmentMenu.add(getAction(TextAlignmentAction.ACTION_RIGHT_ID));
editMenu.appendToGroup(GROUP_EDIT_MENU, textAlignmentMenu);

// Group marker for additional delete actions
editMenu.insertAfter(ArchiActionFactory.DELETE.getId(), new GroupMarker(GROUP_EDIT_DELETE_MENU));

// Delete Container
editMenu.appendToGroup(GROUP_EDIT_DELETE_MENU, getAction(DeleteContainerAction.ID));

return editMenu;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.archimatetool.editor.diagram.actions.BringToFrontAction;
import com.archimatetool.editor.diagram.actions.ConnectionRouterAction;
import com.archimatetool.editor.diagram.actions.DefaultEditPartSizeAction;
import com.archimatetool.editor.diagram.actions.DeleteContainerAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageAction;
import com.archimatetool.editor.diagram.actions.ExportAsImageToClipboardAction;
import com.archimatetool.editor.diagram.actions.LockObjectAction;
Expand Down Expand Up @@ -92,9 +93,14 @@ public void buildContextMenu(IMenuManager menu) {
action = actionRegistry.getAction(ArchiActionFactory.PASTE_SPECIAL.getId());
menu.appendToGroup(GROUP_EDIT, action);

menu.appendToGroup(GROUP_EDIT, new Separator());

action = actionRegistry.getAction(ActionFactory.DELETE.getId());
menu.appendToGroup(GROUP_EDIT, action);

// Delete Container
menu.appendToGroup(GROUP_EDIT, actionRegistry.getAction(DeleteContainerAction.ID));

action = actionRegistry.getAction(LockObjectAction.ID);
if(action.isEnabled()) {
menu.appendToGroup(GROUP_EDIT, new Separator());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
package com.archimatetool.editor.diagram;

import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
Expand All @@ -28,8 +27,6 @@
public class ArchimateDiagramEditorActionBarContributor
extends AbstractDiagramEditorActionBarContributor {

protected static final String editDeleteMenuGroup = "editDeleteMenuGroup"; //$NON-NLS-1$

@Override
protected void buildActions() {
super.buildActions();
Expand Down Expand Up @@ -65,8 +62,8 @@ protected IMenuManager contributeToEditMenu(IMenuManager menuManager) {
}
editMenu.appendToGroup(GROUP_EDIT_MENU, textPositionMenu);

editMenu.insertAfter(ArchiActionFactory.DELETE.getId(), new GroupMarker(editDeleteMenuGroup));
editMenu.appendToGroup(editDeleteMenuGroup, getAction(DeleteFromModelAction.ID));
// Delete from Model
editMenu.appendToGroup(GROUP_EDIT_DELETE_MENU, getAction(DeleteFromModelAction.ID));

return editMenu;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/**
* This program and the accompanying materials
* are made available under the terms of the License
* which accompanies this distribution in the file LICENSE.txt
*/
package com.archimatetool.editor.diagram.actions;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.ui.IWorkbenchPart;

import com.archimatetool.editor.diagram.commands.DiagramCommandFactory;
import com.archimatetool.editor.model.commands.AddListMemberCommand;
import com.archimatetool.editor.model.commands.AlwaysExecutingCompoundCommand;
import com.archimatetool.editor.model.commands.RemoveListMemberCommand;
import com.archimatetool.model.IArchimateFactory;
import com.archimatetool.model.IBounds;
import com.archimatetool.model.IDiagramModelContainer;
import com.archimatetool.model.IDiagramModelObject;
import com.archimatetool.model.ILockable;



/**
* Delete Container object and move children to parent
*
* @author Phillip Beauvoir
*/
public class DeleteContainerAction extends SelectionAction {

public static final String ID = "com.archimatetool.editor.action.deleteContainer"; //$NON-NLS-1$
public static final String TEXT = "Delete from View (keep children)";
public static final String TOOLTIP_TEXT = "Delete from View keeping children";

public DeleteContainerAction(IWorkbenchPart part) {
super(part);
setText(TEXT);
setToolTipText(TOOLTIP_TEXT);
setId(ID);
setActionDefinitionId(ID); // register key binding
}

@Override
protected boolean calculateEnabled() {
return !getObjectsToBeDeleted().isEmpty();
}

@Override
public void run() {
// Execute each command before proceeding to the next in case of multi-selection of embedded containers
// Use a AlwaysExecutingCompoundCommand to ensure redo/undo always execute because cmd#canExecute may return false
CompoundCommand compoundCommand = new AlwaysExecutingCompoundCommand(TEXT) {
@Override
public void execute() {
for(IDiagramModelObject dmo : getObjectsToBeDeleted()) {
IDiagramModelContainer parent = (IDiagramModelContainer)dmo.eContainer();
List<IDiagramModelObject> children = ((IDiagramModelContainer)dmo).getChildren();

// Delete main object
add(DiagramCommandFactory.createDeleteDiagramObjectCommand(dmo, false));

// Iterate thru child objects to move them to new parent
for(IDiagramModelObject child : new ArrayList<>(children)) {
// Remove child from main object
add(new RemoveListMemberCommand<>(children, child));

// Adjust x,y position to new parent
add(new ChangePositionCommand(child, dmo.getBounds()));

// Add child to new parent
add(new AddListMemberCommand<>(parent.getChildren(), child));
}
}
}

@Override
public void add(Command command) {
super.add(command);
command.execute(); // execute command
}
};

execute(compoundCommand);
}

private List<IDiagramModelObject> getObjectsToBeDeleted() {
List<IDiagramModelObject> list = new ArrayList<>();

for(Object object : getSelectedObjects()) {
if(isValidObject(object)) {
list.add((IDiagramModelObject)((EditPart)object).getModel());
}
}

return list;
}

private boolean isValidObject(Object object) {
return object instanceof EditPart editPart && // Is an EditPart
editPart.getModel() instanceof IDiagramModelObject dmo && // Diagram Model Object
dmo instanceof IDiagramModelContainer container && // And a container
dmo.eContainer() instanceof IDiagramModelContainer && // And parent is a container
!(dmo instanceof ILockable lockable && lockable.isLocked()) && // And not locked
!container.getChildren().isEmpty(); // And has child objects
}

private static class ChangePositionCommand extends Command {
private IDiagramModelObject dmo;
private IBounds oldBounds, newBounds;

public ChangePositionCommand(IDiagramModelObject dmo, IBounds parentBounds) {
this.dmo = dmo;
oldBounds = dmo.getBounds();
newBounds = IArchimateFactory.eINSTANCE.createBounds(oldBounds.getX() + parentBounds.getX(),
oldBounds.getY() + parentBounds.getY(), oldBounds.getWidth(), oldBounds.getHeight());
}

@Override
public void execute() {
dmo.setBounds(newBounds);
}

@Override
public void undo() {
dmo.setBounds(oldBounds);
}

@Override
public void dispose() {
dmo = null;
oldBounds = null;
newBounds = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@
public final class DiagramCommandFactory {

/**
* @param object
* @return A new Delete Diagram Object Command
*/
public static Command createDeleteDiagramObjectCommand(IDiagramModelObject object) {
CompoundCommand result = new CompoundCommand();
__addDeleteDiagramObjectCommands(object, result);
return result.unwrap();
return createDeleteDiagramObjectCommand(object, true);
}

/**
* Recurse and add child delete commands.
* We have to do this because if the object has children with connections going outside these need explicit Delete Commands too
* otherwise we end up with trailing connections...
* @param container
* @param result
* @return A new Delete Diagram Object Command with option of deleting child objects
*/
private static void __addDeleteDiagramObjectCommands(IDiagramModelObject object, CompoundCommand result) {
public static Command createDeleteDiagramObjectCommand(IDiagramModelObject object, boolean deleteChildren) {
CompoundCommand result = new CompoundCommand();
addDeleteDiagramObjectCommands(object, result, deleteChildren);
return result.unwrap();
}

private static void addDeleteDiagramObjectCommands(IDiagramModelObject object, CompoundCommand result, boolean deleteChildren) {
result.add(new DeleteDiagramObjectCommand(object));

for(IDiagramModelConnection connection : object.getSourceConnections()) {
Expand All @@ -49,9 +48,9 @@ private static void __addDeleteDiagramObjectCommands(IDiagramModelObject object,
result.add(createDeleteDiagramConnectionCommand(connection));
}

if(object instanceof IDiagramModelContainer) {
for(IDiagramModelObject child : ((IDiagramModelContainer)object).getChildren()) {
__addDeleteDiagramObjectCommands(child, result);
if(deleteChildren && object instanceof IDiagramModelContainer container) {
for(IDiagramModelObject child : container.getChildren()) {
addDeleteDiagramObjectCommands(child, result, deleteChildren);
}
}
}
Expand All @@ -62,11 +61,11 @@ private static void __addDeleteDiagramObjectCommands(IDiagramModelObject object,
*/
public static Command createDeleteDiagramConnectionCommand(IDiagramModelConnection connection) {
CompoundCommand result = new CompoundCommand();
__addDeleteDiagramConnectionCommands(connection, result);
addDeleteDiagramConnectionCommands(connection, result);
return result.unwrap();
}

private static void __addDeleteDiagramConnectionCommands(IDiagramModelConnection connection, CompoundCommand result) {
private static void addDeleteDiagramConnectionCommands(IDiagramModelConnection connection, CompoundCommand result) {
for(IDiagramModelConnection conn : connection.getSourceConnections()) {
result.add(createDeleteDiagramConnectionCommand(conn));
}
Expand Down
17 changes: 11 additions & 6 deletions com.archimatetool.help/help/Text/view_copy_paste_delete.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ <h2>Copy As Image to Clipboard</h2>

<h2>Deleting Elements and Relationships (Connections) in a View</h2>

<p>Selected elements and/or connections in a View can be deleted from the View by choosing the "Delete from View" menu item from the main "Edit" menu, from the main toolbar or from the right-click menu. <em>Note - this action deletes those elements from the View not from the model. To delete the element completely you have to delete it in the Model Tree or select "Delete from Model".</em></p>
<p>Selected elements and/or connections in a View can be deleted from the View by choosing the "Delete from View" menu item from the main "Edit" menu, from the main toolbar or from the right-click menu. <em>Note - this action deletes the selected objects from the View not from the model.</em></p>

<br/>

<h2>Delete from View (keep children)</h2>
<p>This menu item is available from the main "Edit" menu or when right-clicking an object in a View. It allows you to delete the selected objects but retain the object's child objects. Child objects are re-parented to the selected object's immediate parent. <em>Note - this action deletes the selected objects from the View not from the model.</em></p>

<br/>

<h2>Delete from Model</h2>
<p>This menu item is available from the main "Edit" menu or when right-clicking an element or relationship in a View. The selected elements and/or relationships are deleted from the model itself and any Views that reference those elements. This is the equivalent of selecting the elements in the Model Tree and choosing "Delete".</p>

<br/>

Expand All @@ -52,11 +62,6 @@ <h2>Changing an Object's ArchiMate Concept Type in a View</h2>
<h2>Select in Model Tree</h2>
<p>This menu item is available when right-clicking an element or relationship in a View. It will select the corresponding model element in the Model Tree.</p>

<br/>

<h2>Delete from Model</h2>
<p>This menu item is available when right-clicking an element or relationship in a View. The selected elements and/or relationships are then deleted from the model itself and any Views that reference those elements. This is the equivalent of selecting the elements in the Model Tree and choosing "Delete".</p>

<p>&nbsp;</p>

</body>
Expand Down

0 comments on commit 7ad0615

Please sign in to comment.