/***************************************************************************** * Copyright (c) 2010 Atos Origin. * * * 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: * Atos Origin - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.activity.helper; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.activity.edit.helpers.AcceptEventActionEditHelper; import org.eclipse.papyrus.uml.diagram.activity.edit.parts.AcceptEventActionEditPart; import org.eclipse.papyrus.uml.diagram.activity.edit.parts.AcceptEventActionEditPart.AcceptEventActionFigure; import org.eclipse.papyrus.uml.diagram.common.helper.NotificationHelper; import org.eclipse.papyrus.uml.diagram.common.providers.UIAdapterImpl; import org.eclipse.uml2.uml.AcceptEventAction; import org.eclipse.uml2.uml.Trigger; import org.eclipse.uml2.uml.UMLPackage; /** * The AcceptEventActionSwitchHelper class is used to help updating an * AcceptEventAction's figure. It enables to switch between the classic pentagon * representation and the hourglass representation of an AcceptTimeEventAction. */ public class AcceptEventActionSwitchHelper extends NotificationHelper { /** The size factor between the classic figure and the hourglass figure */ private static final int REDUCE_WIDTH_FACTOR_FOR_HOURGLASS = 4; /** * The UI adapter that listens model update to detect when figure switch * must be performed */ private UIAdapter adapter = new UIAdapter(); /** The edit part which this helper handles the switch for */ private AcceptEventActionEditPart editPart; /** * Construct a new switch helper which will automatically manage the switch * when properties are edited. * * @param acceptEventActionEditPart * the part of an AcceptEventAction, for which the switch must be * managed. */ public AcceptEventActionSwitchHelper(AcceptEventActionEditPart acceptEventActionEditPart) { editPart = acceptEventActionEditPart; this.setModelListener(adapter); } /** * Private class UIAdapter. This class listens at appropriate model elements * to detect when an AcceptEventAction becomes an AcceptTimeEventAction. */ private class UIAdapter extends UIAdapterImpl { /** * Notify the changes by updating listened elements if necessary and * performing the switch if necessary. * * @see org.eclipse.papyrus.uml.diagram.common.providers.UIAdapterImpl#safeNotifyChanged(org.eclipse.emf.common.notify.Notification) * @param msg * the notification message */ @Override protected void safeNotifyChanged(Notification msg) { if(UMLPackage.eINSTANCE.getAcceptEventAction_Trigger().equals(msg.getFeature())) { // listen trigger once the list is modified if(msg.getNewValue() instanceof List<?>) { for(Object value : (List<?>)msg.getNewValue()) { if(value instanceof Notifier) { listenObject((Notifier)value); } } } else if(msg.getNewValue() instanceof Notifier) { listenObject((Notifier)msg.getNewValue()); } if(msg.getOldValue() instanceof List<?>) { for(Object value : (List<?>)msg.getOldValue()) { if(value instanceof Notifier) { unlistenObject((Notifier)value); } } } else if(msg.getOldValue() instanceof Notifier) { unlistenObject((Notifier)msg.getNewValue()); } updateAcceptEventActionFigure(); } else if(UMLPackage.eINSTANCE.getTrigger_Event().equals(msg.getFeature())) { updateAcceptEventActionFigure(); } } } /** * Get the AcceptEventAction model element managed by the edit part * * @return AcceptEventAction model element */ public AcceptEventAction getAction() { EObject resolveSemanticElement = editPart.resolveSemanticElement(); if(resolveSemanticElement instanceof AcceptEventAction) { return (AcceptEventAction)resolveSemanticElement; } return null; } /** * Update the figure representation, to switch to or from the hourglass * representation */ public void updateAcceptEventActionFigure() { AcceptEventActionFigure actionFigure = editPart.getPrimaryShape(); boolean useHourglassFigure = AcceptEventActionEditHelper.isAcceptTimeEventAction(getAction()); boolean hourglassAlreadyUsed = actionFigure.isTemplateForAcceptTimeEventActionUsed(); if(useHourglassFigure != hourglassAlreadyUsed) { // set usage of the correct figure actionFigure.useTemplateForAcceptTimeEventAction(useHourglassFigure); // arrange the figure so that style remains coherent if(editPart.getModel() instanceof View) { int locX = actionFigure.getLocation().x; int width = actionFigure.getSize().width; int newWidth = width; if(useHourglassFigure) { // switching to hourglass, reduce width newWidth = width / REDUCE_WIDTH_FACTOR_FOR_HOURGLASS; } else { // switching to pentagon, augment width newWidth = width * REDUCE_WIDTH_FACTOR_FOR_HOURGLASS; } // adapt location to keep same center ViewUtil.setStructuralFeatureValue((View)editPart.getModel(), NotationPackage.eINSTANCE.getLocation_X(), locX + (width - newWidth) / 2); ViewUtil.setStructuralFeatureValue((View)editPart.getModel(), NotationPackage.eINSTANCE.getSize_Width(), newWidth); } } } /** * Add listener on an element and its appropriate children in case of an * AcceptEventAction * * @param element * The object to listen */ @Override public void listenObject(Notifier element) { super.listenObject(element); if(element instanceof AcceptEventAction) { // also listen at children triggers of the action for(Trigger trigger : ((AcceptEventAction)element).getTriggers()) { super.listenObject(trigger); } } } }