/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * * 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: * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.menu.actions; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.commands.UnexecutableCommand; import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils; import org.eclipse.gmf.runtime.diagram.ui.actions.internal.ShowConnectionLabelsAction; import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ConnectionLabelsEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.services.editpart.EditPartService; 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; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.papyrus.uml.diagram.common.commands.ShowHideLabelsRequest; import org.eclipse.papyrus.uml.diagram.common.editparts.ILabelRoleProvider; import org.eclipse.papyrus.uml.diagram.common.util.DiagramEditPartsUtil; import org.eclipse.papyrus.uml.diagram.menu.dialogs.ShowHideLabelSelectionDialog; import org.eclipse.papyrus.uml.diagram.menu.messages.Messages; import org.eclipse.papyrus.uml.tools.providers.UMLLabelProvider; /** * Adapted code from {@link ShowConnectionLabelsAction} * * This action allows to manage connection labels. 3 parameters are available for this actio : * <ul> * <li> {@link #HIDE_PARAMETER} : hide all labels for the selected elements</li> * <li> {@link #SHOW_PARAMETER} : show all labels for the selected elements</li> * <li> {@link #MANAGE_PARAMETER} : open a dialog to choose labels to display and labels to hide for the selected element</li> * </ul> * */ public class ShowHideLabelsAction extends AbstractGraphicalParametricAction { /** * Parameters for this action */ public static final String MANAGE_PARAMETER = "manage"; //$NON-NLS-1$ public static final String HIDE_PARAMETER = "hide"; //$NON-NLS-1$ public static final String SHOW_PARAMETER = "show"; //$NON-NLS-1$ /** * * Constructor. * * @param parameter * the parameter for this action * @param selectedEditPart * the list of selected {@link EditPart} */ public ShowHideLabelsAction(String parameter, List<IGraphicalEditPart> selectedEditPart) { super(parameter, selectedEditPart); } /** * * @see org.eclipse.papyrus.uml.diagram.menu.actions.AbstractGraphicalParametricAction#getBuildedCommand() * * @return */ @Override protected Command getBuildedCommand() { List<IGraphicalEditPart> selections = getSelection(); CompoundCommand cmd = new CompoundCommand("ShowHideConnectionLabelCommand"); //$NON-NLS-1$ if(!selections.isEmpty()) { if(getParameter().equals(MANAGE_PARAMETER)) { ManageLabelsAction action = new ManageLabelsAction(Messages.ShowHideConnectionLabelsAction_LabelsManager, Messages.ShowHideConnectionLabelsAction_SelectTheLabelToDisplay, getSelection()); cmd.add(action.getActionCommand()); } else { /* * we have a problem with the hide action for Hide All Label, * because, this request hide the labels and the port too! * so, we need to use the CustomRequest! */ ContentProvider provider = new ContentProvider(DiagramEditPartsUtil.getDiagramEditPart(selections.get(0))); for(IGraphicalEditPart current : selections) { Object[] children = provider.getChildren(current); for(Object currentObj : children) { if(currentObj instanceof View) { ShowHideLabelsRequest request = null; if(getParameter().equals(HIDE_PARAMETER)) { request = new ShowHideLabelsRequest(false, (View)currentObj); } else if(getParameter().equals(SHOW_PARAMETER)) { request = new ShowHideLabelsRequest(true, (View)currentObj); } if(request != null) { Command tmp = current.getCommand(request); if(tmp != null) { cmd.add(tmp); } } } } } } } return (cmd.canExecute() && !cmd.isEmpty()) ? cmd : UnexecutableCommand.INSTANCE; } /** * Returns the selected connections for the actions * * @return * the selected connections for the actions */ protected List<ConnectionEditPart> getConnections() { List<ConnectionEditPart> connections = new ArrayList<ConnectionEditPart>(); for(IGraphicalEditPart current : getSelection()) { if(current instanceof DiagramEditPart && getSelection().size() == 1) { connections.addAll(((DiagramEditPart)current).getConnections()); break; } else if(current instanceof ConnectionEditPart) { connections.add((ConnectionEditPart)current); } } return connections; } /** * This code comes from {@link ConnectionLabelsEditPolicy} * * determines if the passed view is a label view or not * the default provided implementation is just an educated/generic guss * clients can override this method to provide more specific response * * @param node * @return */ protected boolean isLabelView(EditPart containerEditPart, View parentView, View view) { // labels are not compartments // labels contained by Node Shape Edit Parts or connection edit parts // labels had location constrain // labels had the string Type set on them if((containerEditPart instanceof ShapeNodeEditPart || containerEditPart instanceof ConnectionEditPart) && view instanceof Node) { Node node = (Node)view; String nodeType = node.getType(); if(!isCompartment(node) && (nodeType != null && nodeType.length() > 0)) { LayoutConstraint lContraint = node.getLayoutConstraint(); if(lContraint instanceof Location) { return true; } } } return false; } /** * * This code comes from {@link ConnectionLabelsEditPolicy} * * determines if the passed view is a compartment view or not * the default provided implementation is just an educated/generic guss * clients can override this method to provide more specific response * * @param node * @return */ protected boolean isCompartment(Node node) { if(node.getStyle(NotationPackage.eINSTANCE.getDrawerStyle()) != null) { return true; } return false; } // @Override // public boolean isEnabled() { // if(super.isEnabled()) { // for(IGraphicalEditPart current : getSelection()) { // if(current.getEditPolicy(ShowHideLabelEditPolicy.SHOW_HIDE_LABEL_ROLE) == null) { // return false; // } // } // } // return true; // } /** * This class provides a dialog to manage the displaying of the labels for connections * * * */ public class ManageLabelsAction { /** * This map is used to store the new states of the labels * the {@link View} are the keys for this map and the associated value is a {@link Boolean}. * This Boolean represents the new value for the display state. */ protected Map<View, Boolean> viewStatus = new HashMap<View, Boolean>(); /** Title for the dialog */ private String title; /** Message for the dialog */ private String message; /** the list of connections to manage */ private List<IGraphicalEditPart> editparts; /** * * Constructor. * * @param title * @param message * @param editPolicyKey */ public ManageLabelsAction(String title, String message, List<IGraphicalEditPart> editparts) { this.title = title; this.message = message; this.editparts = editparts; initMap(); } /** * Returns the command for this action * * @return * the command for this action */ protected Command getActionCommand() { CompoundCommand cmd = new CompoundCommand("Manage Conection Labels "); //$NON-NLS-1$ DiagramEditPart diagramEP = DiagramEditPartsUtil.getDiagramEditPart(editparts.get(0)); ShowHideLabelSelectionDialog selectionDialog = new ShowHideLabelSelectionDialog(DisplayUtils.getDisplay().getActiveShell(), new UMLLabelProvider(), new ContentProvider(diagramEP)); selectionDialog.setTitle(this.title); selectionDialog.setMessage(this.message); selectionDialog.setContainerMode(true); selectionDialog.setInput(editparts); selectionDialog.setExpandedElements(editparts.toArray()); selectionDialog.setInitialElementSelections(getInitialSelection()); selectionDialog.open(); if(selectionDialog.getReturnCode() == Dialog.OK) { Object[] userSelection = selectionDialog.getResult(); //fill the map with the new values for(Object current : userSelection) { if(current instanceof EditPart) { //do nothing } else if(current instanceof View) { viewStatus.put((View)current, new Boolean(true)); } } /** * Creates the commands for this action */ for(View view : viewStatus.keySet()) { boolean oldStatus = view.isVisible(); boolean newStatus = viewStatus.get(view).booleanValue(); if(oldStatus == newStatus) { //do nothing } else { if(oldStatus) { EditPart ep = DiagramEditPartsUtil.getEditPartFromView(view, getSelection().get(0)); int dummy = 0; dummy++; } ShowHideLabelsRequest request = new ShowHideLabelsRequest(newStatus, view); // EditPart ep = DiagramEditPartsUtil.getEditPartFromView(view, getConnections().get(0)); EditPart ep = DiagramEditPartsUtil.getEditPartFromView(view, getSelection().get(0)); // EditPart ep = DiagramEditPartsUtil.getEditPartFromView(view, diagramEP); //Command command = ep.getParent().getCommand(request); Command command = ep.getParent().getCommand(request); if(command != null) { cmd.add(command); } } } return cmd; } return UnexecutableCommand.INSTANCE; } /** * Returns the initial selection * * @return * the initial selection : the view that are currently displayed */ public List<View> getInitialSelection() { List<View> selection = new ArrayList<View>(); // for(ConnectionEditPart current : getConnections()) { // View model = (View)(current).getModel(); // Iterator<?> iter = model.getChildren().iterator(); // while(iter.hasNext()) { // View childView = (View)iter.next(); // if(isLabelView(current, model, childView)) { // if(childView.isVisible()) { // selection.add(childView); // } // } // } // } for(IGraphicalEditPart current : getSelection()) { View model = (View)(current).getModel(); Iterator<?> iter = model.getChildren().iterator(); while(iter.hasNext()) { View childView = (View)iter.next(); if(isLabelView(current, model, childView)) { if(childView.isVisible()) { selection.add(childView); } } } } return selection; } /** * put all the available views in the map, with the value <code>false</code> */ public void initMap() { viewStatus.clear(); // for(EditPart current : getConnections()) { for(EditPart current : getSelection()) { View model = (View)((IGraphicalEditPart)current).getModel(); Iterator<?> iter = model.getChildren().iterator(); while(iter.hasNext()) { View childView = (View)iter.next(); if(isLabelView(current, model, childView)) { viewStatus.put(childView, new Boolean(false)); } } } } } /** * * Provide the element to fill the tree * */ protected class ContentProvider implements ITreeContentProvider { /** * the diagram EditPart. It's used to find the editpart corresponding to a view */ private DiagramEditPart diagramEP; /** * * Constructor. * * @param diagramEP * the diagram editpart. Used to find editpart corresponding to a view */ public ContentProvider(DiagramEditPart diagramEP) { this.diagramEP = diagramEP; } /** * * @see org.eclipse.jface.viewers.IContentProvider#dispose() * */ public void dispose() { // TODO Auto-generated method stub } /** * * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) * * @param viewer * @param oldInput * @param newInput */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // TODO Auto-generated method stub } /** * * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object) * * @param inputElement * @return */ public Object[] getElements(Object inputElement) { if(inputElement instanceof List) { return ((List<?>)inputElement).toArray(); } return new Object[0]; } /** * * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) * * @param parentElement * @return */ public Object[] getChildren(Object parentElement) { List<View> children = new ArrayList<View>(); // if(parentElement instanceof ConnectionEditPart) { if(parentElement instanceof EditPart) { View model = (View)((EditPart)parentElement).getModel(); Iterator<?> iter = model.getChildren().iterator(); while(iter.hasNext()) { View childView = (View)iter.next(); if(isLabelView((EditPart)parentElement, model, childView)) { children.add(childView); } } } Collections.sort(children, new LabelRoleComparator()); return children.toArray(); } /** * * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) * * @param element * @return */ public Object getParent(Object element) { if(element instanceof View) { EditPart part = DiagramEditPartsUtil.getEditPartFromView((View)element, diagramEP); return part.getParent(); } return null; } /** * * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) * * @param element * @return */ public boolean hasChildren(Object element) { Object[] children = getChildren(element); return children != null && children.length != 0; } } public class LabelRoleComparator implements Comparator<View> { public int compare(View o1, View o2) { EditPart ep1 = EditPartService.getInstance().createGraphicEditPart(o1); EditPart ep2 = EditPartService.getInstance().createGraphicEditPart(o2); if(ep1 instanceof ILabelRoleProvider && ep2 instanceof ILabelRoleProvider) { String role1 = ((ILabelRoleProvider)ep1).getLabelRole(); String role2 = ((ILabelRoleProvider)ep2).getLabelRole(); return role1.compareToIgnoreCase(role2); } return 0; } } @Override public List<IGraphicalEditPart> getSelection() { List<IGraphicalEditPart> selection = super.getSelection(); List<IGraphicalEditPart> delete = new ArrayList<IGraphicalEditPart>(); Iterator<IGraphicalEditPart> iter = selection.iterator(); // while(iter.hasNext()) { // IGraphicalEditPart current = iter.next(); // if(Util.isAffixedChildNode(current)) { // delete.remove(current); // } // } selection.removeAll(delete); return selection; } }