/* Manages undo/redo actions on a MoML model. Copyright (c) 2000-2014 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY */ package ptolemy.moml; import ptolemy.kernel.undo.UndoAction; import ptolemy.kernel.util.ChangeListener; import ptolemy.kernel.util.ChangeRequest; import ptolemy.kernel.util.NamedObj; /////////////////////////////////////////////////////////////////// //// MoMLUndoEntry /** This is an undo action on the undo/redo stack. The undo/redo stack is stored in an instance of UndoInfoAttribute associated with the top-level of a model. If undo/redo is enabled, a MoMLParser will create entries automatically and put them on the stack whenever it parses MoML. So the easiest mechanism to perform undoable actions is to specify those actions in MoML and issue a MoMLChangeRequest to execute them. An alternative, however, is to create an instance of this class with no MoML, using the single argument constructor, and to override execute() to directly perform the undo. @see MoMLParser @see ptolemy.kernel.undo.UndoStackAttribute @see MoMLChangeRequest @author Neil Smyth and Edward A. Lee @version $Id: MoMLUndoEntry.java 70398 2014-10-22 23:44:32Z cxh $ @since Ptolemy II 2.1 @Pt.ProposedRating Yellow (eal) @Pt.AcceptedRating Red (cxh) */ public class MoMLUndoEntry implements UndoAction, ChangeListener { /** Create an undo entry comprised of the specified MoML code. * @param context The context in which to execute the undo. * @param undoMoML The MoML specification of the undo action. */ public MoMLUndoEntry(NamedObj context, String undoMoML) { _context = context; _undoMoML = undoMoML; } /////////////////////////////////////////////////////////////////// //// public methods //// /** Do nothing. This method is called when a change is successfully * executed. * @param change The change that was successfully executed. */ @Override public void changeExecuted(ChangeRequest change) { // In case this has been set before... _exception = null; } /** Record the exception so that execute() can throw it. * @param change The change that failed. * @param exception The exception that occurred. * @see #execute() */ @Override public void changeFailed(ChangeRequest change, Exception exception) { _exception = exception; } /** Parse the MoML specified in the constructor call in the context * specified in the constructor call using the parser associated * with the context (as determined by ParserAttribute.getParser()). * @see ParserAttribute#getParser(NamedObj) */ @Override public void execute() throws Exception { // If the MoML is empty, the parser will throw an exception. if (_undoMoML == null || _undoMoML.trim().equals("")) { // Nothing to do. return; } // Use a MoMLChangeRequest so that changes get propagated // as appropriate to models that defer to this. MoMLChangeRequest request = new MoMLChangeRequest(this, _context, _undoMoML); // An undo entry is always undoable so that redo works. request.addChangeListener(this); request.setUndoable(true); request.execute(); // The above call will result in a call to changeFailed() // if the execution fails. if (_exception != null) { throw _exception; } } /** Return the MoML of the undo action. * @return MoML for the undo action. */ @Override public String toString() { return _undoMoML + "\n...in context: " + _context.getFullName(); } /////////////////////////////////////////////////////////////////// //// private variables //// // The context in which to execute the undo. private NamedObj _context; // Exception that occurs during a change. private Exception _exception = null; // The MoML specification of the undo. private String _undoMoML; }