Last modified: December 2015

URL: https://cxc.cfa.harvard.edu/chips/ahelp/undo.html
AHELP for CIAO 4.11 ChIPS v1

undo

Context: undo

Synopsis

Undoes the last command or series of commands.

Syntax

undo()
undo(count)
undo(tag)

Description

The function arguments.

Argument Description
count The number of commands to undo (default is 1).
tag The name of a tag created with set_undo_tag.

The undo command allows the user to reverse one or more commands. If called without any arguments, the last executed command is undone. The undo functionality is extended by using tags and blocks, which are described below.

The redo command is used to repeat a command or series of commands that was undone.


Examples

Example 1

chips> set_frame(["bgcolor","red"])
chips> undo()

Make the frame background red, then undo the command. The redo command can be used to revert the change; for example

chips> redo()

Example 2

chips> set_frame(["bgcolor","red"])
chips> set_frame(["bgcolor","orange"])
chips> set_frame(["bgcolor","yellow"])
chips> set_undo_tag("yellow")
chips> set_frame(["bgcolor","green"])
chips> set_undo_tag("green")
chips> set_frame(["bgcolor","blue"])
chips> undo("yellow")
chips> undo(2)

A tag is added to the undo stack after the frame background color is set to yellow. The color is then changed to green and another tag is added. After changing the background color to blue, undo is called with the yellow tag. Undo is then called with the value "2" to return to the red background, which is two commands prior to the yellow tag.

Example 3

chips> add_contour([1,2,5,3,3,6,0,0,1],3,3)
chips> open_undo_block()
chips> set_preference("region.fill.style", "1")
chips> add_region([1,1,2,2.32,2],[1.5,2,2,1,1],"fill.color=blue")
chips> add_region([3,2.67,3],[1,2,2.2],"fill.color=lime")
chips> add_label(1.7,1.7,r"\lambda")
chips> close_undo_block()
chips> undo()
chips> set_preference("region.fill.style", "1");

Three commands - two add_region and one add_label - are marked as a block. The undo command undoes all three commands.

Example 4

chips> add_contour([1,2,5,3,3,6,0,0,1],3,3)
chips> open_undo_buffer()
chips> set_preference("region.fill.style", "1")
chips> add_region([1,1,2,2.32,2],[1.5,2,2,1,1],"fill.color=blue")
chips> add_region([3,2.67,3],[1,2,2.2],"fill.color=lime")
chips> add_label(1.7,1.7,r"\lambda")
chips> close_undo_buffer()
chips> undo()
chips> redo()
chips> set_preference("region.fill.style", "1");

Add a contour, then open a buffer. Two regions and a label are overlayed on the contour. The close_undo_buffer command flattens those three additions into a single operation and display them to the user. The subsequent undo and redo commands show that the commands within the block are treated as an atomic unit.

Normally you would want to run all the commands between the open_undo_buffer and close_undo_buffer commands within a try block, as explained in a later example.

Example 5

chips> add_vline (0.5,"color=purple")
chips> open_undo_buffer()
chips> add_label(0.4,0.5,"DELTA")
chips> set_label_color("gold")
chips> set_label_font("times")
chips> set_label_size(20)
chips> discard_undo_buffer()
chips> undo()
chips> redo()

A sequence of label commands are put into an undo buffer. Since the sequence ends with a discard_undo_buffer - rather than close_undo_buffer - the four commands are erased and are never displayed to the screen. The undo and redo commands threefore apply only to the add_vline command.

Example 6

open_undo_buffer()
try:
    add_curve ([1,2,3,4],[4,0,6,-1])

    set_cascading_property (chips_curve, "color", "purple")
except:
    discard_undo_buffer()
    raise
else:
    close_undo_buffer()

open_undo_buffer()
try:
    add_curve ([1,2,3,4],[10,5,20,-5])
    set_cascading_property (chips_curve, "color", "blu")
except:
    discard_undo_buffer()
    raise
else:
    close_undo_buffer()
  

This example shows how the discard buffer can be used with Python's exception handling. A curve is added and the color is set to purple; both commands are successful. A second curve is added and the color is set to blue. The typo in set_cascading_property ("blu" instead of "blue") is caught, and the set of commands is discarded.


The Undo and Redo Stacks

ChIPS maintains two stacks - an undo stack and a redo stack. When commands are executed, they are added to the undo stack. When undo is called, ChIPS pops the commands off the undo stack and pushes them onto the redo stack. Redoing the commands pops them off the redo stack and back onto the undo stack.

Redo only works if commands have been undone and exist in the redo stack. After an undo command, if any command is issued that gets added to the undo stack, the redo stack gets cleared and those undone actions are no longer available.

Note that not all commands may be undone, such as file commands (printing and saving). Commands which retrieve information (such as get_<attribute> or info) also cannot be undone.

Using tags, blocks, and buffers

Tags

A tag may be set to mark a point in the command history. The tag can later be used to undo and redo all commands back to that point. The command to create a tag is set_undo_tag(tagname). To remove an existing tag, use clear_undo_tag(tagname).

chips> set_undo_tag('plot1')
...
chips> undo('plot1')

An undo tag may be added within a block, but is only valid until the block is closed.

Blocks

Multiple commands may be grouped together in blocks so that they are treated as a unit by the undo and redo commands. When an undo is issued on a block, all of the commands in the block are undone as a single step. A redo command can then reverse the block undo. The commands open_undo_block and close_undo_block are used to open and close the block. These commands are part of the advanced ChIPS module; refer to "ahelp chips" for information. To load the module:

from pychips.advanced import *

The commands are not grouped until the block is closed. If undo is called while a block is open, the last single command is undone.

Buffers

Multiple commands may be grouped together in buffers by the open_undo_buffer and close_undo_buffer commands. Buffers are similar to blocks, but the window display is not updated until the buffer is closed; block commands update the display as they are issued.

Additionally, the discard_undo_buffer command may be used instead of close_undo_buffer. This discard command allows the user to effectively undo all the commands in that were issued while the buffer was open, without leaving them on the undo stack.

As an example:

import pycrates
import pychips
import pychips.advanced as advanced

import numpy as np

# Allow the routine to be imported
__all__ = ("shade_error_region", )

def error_region(filename):
    "The first 3 columns of file are assumed to be x, y, dy"

    cr = pycrates.read_file(filename)
    xcol = cr.get_column(0)
    ycol = cr.get_column(1)
    dycol = cr.get_column(2)

    # Column values
    x = xcol.values
    y = ycol.values
    dy = dycol.values

    # The vertexes of the histogram
    yl = y - dy
    yh = y + dy
    xr = np.append(x, x[::-1])
    yr = np.append(yl, yh[::-1])

    # Axis labels from column name and, if present, units
    xlbl = xcol.name
    if xcol.unit != '':
        xlbl += " ({})".format(xcol.unit)

    ylbl = ycol.name
    if ycol.unit != '':
        ylbl += " ({})".format(ycol.unit)

    advanced.open_undo_buffer()
    try:
        pychips.add_window(8, 6, 'inches')
        
        pychips.add_curve(x, y, dy)
        pychips.add_region(xr, yr, ['fill.style', 'solid'])

        pychips.set_plot_xlabel(xlbl)
        pychips.set_plot_ylabel(ylbl)
        pychips.set_plot_title(filename)

    except:
        # Throw away all the comands since the open buffer
        # call and re-raise the error
        advanced.discard_undo_buffer()
        raise

    else:
        # Code was successful, so close the block
        advanced.close_undo_buffer()

If saved to the file shade.py then an example of its use would be

chips> import shade
chips> shade.error_region('tbl.dat')
chips> chips-4> print(info())
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.15)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      Curve [crv1]
      X Axis [ax1]
      Y Axis [ay1]
      Region [reg1]

chips> undo()
chips> print(info())
None

Bugs

See the bugs pages on the ChIPS website for an up-to-date listing of known bugs.

See Also

undo
redo