/******************************************************************************* * Copyright (c) 2010-2015 Henshin developers. All rights reserved. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * TU Berlin, University of Luxembourg, SES S.A. *******************************************************************************/ package de.tub.tfs.henshin.tggeditor.actions; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Vector; import org.eclipse.emf.henshin.model.Graph; import org.eclipse.emf.henshin.model.Node; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.ui.actions.SelectionAction; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IWorkbenchPart; import de.tub.tfs.henshin.tgg.TGG; import de.tub.tfs.henshin.tgg.TNode; import de.tub.tfs.henshin.tgg.TripleComponent; import de.tub.tfs.henshin.tgg.interpreter.util.NodeUtil; import de.tub.tfs.henshin.tggeditor.TGGEditorActivator; import de.tub.tfs.henshin.tggeditor.commands.delete.DeleteManyNodesCommand; import de.tub.tfs.henshin.tggeditor.ui.TGGEditorConstants; import de.tub.tfs.henshin.tggeditor.util.GraphicalNodeUtil; /** * This action removes all nodes of the selected TGG components * * @author "Frank Hermann" */ public class RestrictGraphAction extends SelectionAction { public static final String ID = "RestrictGraphAction"; private static final String DESC = "Removes components of the graph"; private static final String LABEL = "Restric graph"; static final ArrayList<String> restrictionTypeNames = new ArrayList<String>(); /** * the restriction types for the subsets of components of a triple graph */ static final ArrayList<ArrayList<TripleComponent>> restrictionTypes = new ArrayList<ArrayList<TripleComponent>>(); /** the command that deletes all nodes of the chosen components */ private CompoundCommand compCommand; static { ArrayList<TripleComponent> removeSource = new ArrayList<TripleComponent>(); ArrayList<TripleComponent> removeCorrespondence = new ArrayList<TripleComponent>(); ArrayList<TripleComponent> removeTarget = new ArrayList<TripleComponent>(); ArrayList<TripleComponent> removeSourceCorrespondence = new ArrayList<TripleComponent>(); ArrayList<TripleComponent> removeCorrespondenceTarget = new ArrayList<TripleComponent>(); removeSource.add(TripleComponent.SOURCE); removeCorrespondence.add(TripleComponent.CORRESPONDENCE); removeTarget.add(TripleComponent.TARGET); removeSourceCorrespondence.add(TripleComponent.SOURCE); removeSourceCorrespondence.add(TripleComponent.CORRESPONDENCE); removeCorrespondenceTarget.add(TripleComponent.CORRESPONDENCE); removeCorrespondenceTarget.add(TripleComponent.TARGET); restrictionTypes.add(removeSource); restrictionTypes.add(removeCorrespondence); restrictionTypes.add(removeTarget); restrictionTypes.add(removeSourceCorrespondence); restrictionTypes.add(removeCorrespondenceTarget); restrictionTypeNames.add("[S] Remove source component"); restrictionTypeNames.add("[C] Remove correspondence component"); restrictionTypeNames.add("[T] Remove target component"); restrictionTypeNames.add("[S+C] Remove source and correspondence components"); restrictionTypeNames.add("[C+T] Remove correspondence and target components"); } /** * the viewer containing the currently selected GraphicalEditPart */ private EditPartViewer viewer; /** * the currently selected layout algorithm */ ArrayList<TripleComponent> currentRestrictionType; /** * The constructor prepares the menu to selected the layout algorithm from * * @param part * the workbench part */ public RestrictGraphAction(final IWorkbenchPart part) { super(part); setId(ID); setText(LABEL); setDescription(DESC); setToolTipText(DESC); setImageDescriptor(TGGEditorActivator.getImageDescriptor(TGGEditorConstants.ICON_DELETE_18)); currentRestrictionType = restrictionTypes.get(0); setMenuCreator(new IMenuCreator() { Menu menu; @Override public void dispose() { if (menu != null) { menu.dispose(); menu = null; } } @Override public Menu getMenu(final Control parent) { if (menu == null) { menu = new Menu(parent); fillMenu(); } return menu; } @Override public Menu getMenu(final Menu parent) { // not intended as submenu return null; } private void fillMenu() { for (final String restrictionTypeName : restrictionTypeNames) { final MenuItem item = new MenuItem(menu, SWT.RADIO); item.setText(restrictionTypeName); item.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { final int index = menu.indexOf((MenuItem) e.widget); currentRestrictionType = restrictionTypes.get(index); } }); } // select first item by default menu.getItem(0).setSelection(true); } }); } /** * Gets the Graph Layout Command and executes it. */ @SuppressWarnings("unchecked") @Override public void run() { // when invoking directly, a viewer must be set manually! if (viewer == null) { return; } // Graph graph=null; TGG tgg=null; compCommand = new CompoundCommand(); if (viewer.getContents().getModel() instanceof Graph) graph = (Graph) viewer.getContents().getModel(); if (graph != null) tgg = GraphicalNodeUtil.getLayoutSystem(graph); if (tgg!=null) removeNodes(tgg,currentRestrictionType); } private void removeNodes(TGG tgg, ArrayList<TripleComponent> restrictionType) { List<Node> nodesToDelete = new Vector<Node>(); for (final EditPart editPart : (Collection<EditPart>) viewer.getContents().getChildren()) { if (editPart instanceof NodeEditPart) { TNode node = (TNode) editPart.getModel(); if( (NodeUtil.isSourceNode(node) && (restrictionType.contains(TripleComponent.SOURCE)) ) || (NodeUtil.isCorrespondenceNode(node) && (restrictionType.contains(TripleComponent.CORRESPONDENCE)) ) || (NodeUtil.isTargetNode(node) && (restrictionType.contains(TripleComponent.TARGET)) ) ){ nodesToDelete.add((Node) editPart.getModel()); } else { } } } Command cmd = new DeleteManyNodesCommand(nodesToDelete); execute(cmd); } /** * This setter allows universal usage of this action. Just call the * constructor with <code>null</code> and set the algorithm for layout * manually. * * @param name * the name of the algorithm to use. Must be one of * {@value #restrictionTypes}. * @see #setViewer(EditPartViewer) */ public void setRestrictionType(final String name) { currentRestrictionType = restrictionTypes.get(restrictionTypeNames.indexOf(name)); } /** * This setter allows universal usage of this action. Just call the * constructor with <code>null</code> and set the viewer for layout * manually. * * @param viewer * @see #setRestrictionType(String) */ public void setViewer(final EditPartViewer viewer) { this.viewer = viewer; } /** * This action is enabled if some graphical edit part is currently selected * from which a viewer can be determined to be trimmed. */ @Override protected boolean calculateEnabled() { viewer = null; if (getSelection() == null) { return false; } if (getSelection() instanceof IStructuredSelection) { final IStructuredSelection selection = (IStructuredSelection) getSelection(); for (final Object selectedObject : selection.toList()) { if (selectedObject instanceof GraphicalEditPart) { viewer = ((GraphicalEditPart) selectedObject).getViewer(); return viewer != null; } } } return false; } }