/******************************************************************************* * CogTool Copyright Notice and Distribution Terms * CogTool 1.3, Copyright (c) 2005-2013 Carnegie Mellon University * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * CogTool is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * CogTool is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CogTool; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * CogTool makes use of several third-party components, with the * following notices: * * Eclipse SWT version 3.448 * Eclipse GEF Draw2D version 3.2.1 * * Unless otherwise indicated, all Content made available by the Eclipse * Foundation is provided to you under the terms and conditions of the Eclipse * Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this * Content and is also available at http://www.eclipse.org/legal/epl-v10.html. * * CLISP version 2.38 * * Copyright (c) Sam Steingold, Bruno Haible 2001-2006 * This software is distributed under the terms of the FSF Gnu Public License. * See COPYRIGHT file in clisp installation folder for more information. * * ACT-R 6.0 * * Copyright (c) 1998-2007 Dan Bothell, Mike Byrne, Christian Lebiere & * John R Anderson. * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * Apache Jakarta Commons-Lang 2.1 * * This product contains software developed by the Apache Software Foundation * (http://www.apache.org/) * * jopt-simple version 1.0 * * Copyright (c) 2004-2013 Paul R. Holser, Jr. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Mozilla XULRunner 1.9.0.5 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/. * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The J2SE(TM) Java Runtime Environment version 5.0 * * Copyright 2009 Sun Microsystems, Inc., 4150 * Network Circle, Santa Clara, California 95054, U.S.A. All * rights reserved. U.S. * See the LICENSE file in the jre folder for more information. ******************************************************************************/ package edu.cmu.cs.hcii.cogtool.model; import java.io.IOException; import java.util.EventObject; import edu.cmu.cs.hcii.cogtool.util.GlobalAttributed; import edu.cmu.cs.hcii.cogtool.util.IEllipsizer; import edu.cmu.cs.hcii.cogtool.util.KeyDisplayUtil; import edu.cmu.cs.hcii.cogtool.util.L10N; import edu.cmu.cs.hcii.cogtool.util.ObjectLoader; import edu.cmu.cs.hcii.cogtool.util.ObjectSaver; import edu.cmu.cs.hcii.cogtool.util.IEllipsizer.IdentityEllipsizer; /** * A Transition represents change in user interface state from one * Frame to another when a specific Action is performed on a Widget * in the source Frame. * <p> * Each Transition knows its source Widget, its destination Frame, * and the Action that causes the change in state to occur. * <p> * This implementation keeps track of the destination Frame * and user Action, but delegates the source Widget query * to the destination Frame. * * @author mlh */ public class Transition extends GlobalAttributed implements TransitionDelay { public static class DestinationChange extends EventObject { protected Frame oldDestination; public DestinationChange(Transition transition, Frame oldDest) { super(transition); oldDestination = oldDest; } public Frame getOldDestination() { return oldDestination; } } public static class ActionChange extends EventObject { protected AAction oldAction; public ActionChange(Transition transition, AAction oldAct) { super(transition); oldAction = oldAct; } public AAction getOldAction() { return oldAction; } } public static class SourceChange extends EventObject { protected TransitionSource oldSource; public SourceChange(Transition trans, TransitionSource oldSrc) { super(trans); oldSource = oldSrc; } public TransitionSource getOldSource() { return oldSource; } } public static class DelayChange extends EventObject { public DelayChange(Transition trans) { super(trans); } } //used for generating bezier curves protected int curveIndex = 0; protected Transition.DestinationChange destinationChgEvent = new Transition.DestinationChange(this, null); protected Transition.SourceChange sourceChgEvent = new Transition.SourceChange(this, null); protected Transition.ActionChange actionChgEvent = new Transition.ActionChange(this, null); public static final int edu_cmu_cs_hcii_cogtool_model_Transition_version = 0; protected static final String sourceVAR = "source"; protected static final String destinationVAR = "destination"; protected static final String actionVAR = "action"; protected static final String curveIndexVAR = "connectionCount"; protected static final String delayInSecsVAR = "delayInSecs"; protected static final String delayLabelVAR = "delayLabel"; protected TransitionSource source; protected Frame destination; protected AAction action; protected double delayInSecs = 0.0; protected String delayLabel = null; private static ObjectSaver.IDataSaver<Transition> SAVER = new ObjectSaver.ADataSaver<Transition>() { @Override public int getVersion() { return edu_cmu_cs_hcii_cogtool_model_Transition_version; } @Override public void saveData(Transition v, ObjectSaver saver) throws IOException { saver.saveObject(v.source, sourceVAR); saver.saveObject(v.destination, destinationVAR); saver.saveObject(v.action, actionVAR); saver.saveInt(v.curveIndex, curveIndexVAR); saver.saveDouble(v.delayInSecs, delayInSecsVAR); saver.saveString(v.delayLabel, delayLabelVAR); } }; public static void registerSaver() { ObjectSaver.registerSaver(Transition.class.getName(), SAVER); } private static ObjectLoader.IObjectLoader<Transition> LOADER = new ObjectLoader.AObjectLoader<Transition>() { @Override public Transition createObject() { return new Transition(); } @Override public void set(Transition target, String variable, Object value) { if (variable != null) { if (variable.equals(sourceVAR)) { target.source = (TransitionSource) value; } else if (variable.equals(destinationVAR)) { target.destination = (Frame) value; } else if (variable.equals(actionVAR)) { target.action = (AAction) value; } else if (variable.equals(delayLabelVAR)) { target.delayLabel = (String) value; } } } @Override public void set(Transition target, String variable, int value) { if (variable != null) { if (variable.equals(curveIndexVAR)) { target.curveIndex = value; } } } @Override public void set(Transition target, String variable, double value) { if (variable != null) { if (variable.equals(delayInSecsVAR)) { target.delayInSecs = value; } } } }; public static void registerLoader() { ObjectLoader.registerLoader(Transition.class.getName(), edu_cmu_cs_hcii_cogtool_model_Transition_version, LOADER); } /** * Checks if 2 objects are identical */ static public boolean isIdentical(Transition l, Transition r) { return ((l.destination == r.destination) || ((l.destination != null) && l.destination.equals(r.destination))) && ((l.action == r.action) || ((l.destination != null) && l.action.equals(r.action))) ; } /** * Initializes the Transition with the given destination Frame * and user Action. * * @param src the transition source * @param dest the destination Frame * @param widgetAction the user Action required to use this Transition * @author mlh */ public Transition(TransitionSource src, Frame dest, AAction widgetAction) { source = src; destination = dest; action = widgetAction; } /** * Zero-argument constructor for use by loading. */ protected Transition() { } /** * Sets the transition's connectionCount to the number of * transitions from the same source to same target + 1. * This is used for drawing bezier lines. * * @author AlexF */ public void setCurveIndex(int index) { curveIndex = index; } /** * Returns the number of connections that have the same source * and target. This is used for drawing bezier lines. * @return the transition's connection count * @author AlexF */ public int getCurveIndex() { return curveIndex; } /** * Returns the source on which the Action should be * performed in order to effect the change in user interface state. * * @return the source of the Transition * @author mlh */ public TransitionSource getSource() { return source; } /** * Sets the source for this Transition. * @param src the new source object */ public void setSource(TransitionSource src) { sourceChgEvent.oldSource = source; source = src; raiseAlert(sourceChgEvent); } /** * Returns the destination Frame representing the new * user interface state after the Transition occurs. * * @return the destination user interface "state" represented by a Frame * @author mlh */ public Frame getDestination() { return destination; } /** * @param dest */ public void setDestination(Frame newDestination) { if (destination != null) { destination.removeIncidentTransition(this); destinationChgEvent.oldDestination = destination; destination = newDestination; destination.addIncidentTransition(this); source.assignCurveIndex(this); raiseAlert(destinationChgEvent); } else { destination = newDestination; } } /** * Returns the Action the user must perform in order to cause * the change to occur represented by this Transition. * * @return the Action that causes this Transition to occur * @author mlh */ public AAction getAction() { return action; } /** * Change the Action the user must perform in order to cause * the change to occur represented by this Transition. * * @param newAction the new Action that should cause this Transition * to occur * @author mlh */ public void setAction(AAction newAction) { if (action != null) { actionChgEvent.oldAction = action; action = newAction; getSource().resetAction(this, actionChgEvent.oldAction); raiseAlert(actionChgEvent); } else { action = newAction; } } /** * Create a "deep" copy of this transition. * <p> * It is the responsibility of the caller to "place" the copy * (usually by adding it to an ITransitionSource). * * @param newSource the actual source of the transition; if * <code>null</code>, uses the current source * @param duplicator the manager of duplicate Frame instances * @return the transition copy * @author mlh */ public Transition duplicate(TransitionSource newSource, Frame.IFrameDuplicator duplicator) { Transition newTransition = new Transition((newSource != null) ? newSource : source, duplicator.getOrDuplicate(destination), action.duplicate()); newTransition.setDelayInfo(getDelayInSecs(), getDelayLabel()); newTransition.copyAttributes(this); return newTransition; } public void setDelayInfo(double delay, String label) { delayInSecs = delay; delayLabel = label; raiseAlert(new Transition.DelayChange(this)); } public String getDelayLabel() { return ((delayLabel == null) || "".equals(delayLabel)) ? DEFAULT_DELAY_LABEL : delayLabel; } public double getDelayInSecs() { return delayInSecs; } public String toString(boolean full) { return toString(full, IdentityEllipsizer.ONLY); } /** * If <code>full</code>, return a string of the type "Transition from * [source name] ([source frame name]) to [target frame name]". Otherwise, * return "[displayed action string]: [target frame name]". * Note: if full is false, it assumes the string will be used for something * whose font is FontUtils.SYMBOL_FONT. */ public String toString(boolean full, IEllipsizer ellipsizer) { String result; String sourceName = source.getNameLabel(); String sourceFrameName = ellipsizer.ellipsize(source.getFrame().getName()); String destName = ellipsizer.ellipsize(destination.getName()); if (full) { result = L10N.get("DE.TransitionStatus", "Transition from") + " " + sourceName + " " + L10N.get("DE.In", "in") + sourceFrameName + " " + L10N.get("DE.To", "to") + " " + destName; } else { String actionLabel = action.getLocalizedString(); result = KeyDisplayUtil.convertActionToDisplay(actionLabel) + ": " + destName; } return result; } }