class Fox::FXUndoList

The undo list manages a list of undoable (and redoable) commands for a FOX application; it works hand-in-hand with subclasses of FXCommand and is an application of the well-known Command pattern. Your application code should implement any number of command classes and then add then to an FXUndoList instance. For an example of how this works, see the textedit example program from the FXRuby distribution.

Class Constants

FXUndoList::ID_UNDO

Message identifier for the undo method. When a SEL_COMMAND message with this identifier is sent to an undo list, it undoes the last command. FXUndoList also provides a SEL_UPDATE handler for this identifier, that enables or disables the sender depending on whether it's possible to undo.

FXUndoList::ID_UNDO_ALL

Message identifier for the “undo all” method. FXUndoList handles both the SEL_COMMAND and SEL_UPDATE messages for this message identifier.

FXUndoList::ID_REDO

Message identifier for the redo method. When a SEL_COMMAND message with this identifier is sent to an undo list, it redoes the last command. FXUndoList also provides a SEL_UPDATE handler for this identifier, that enables or disables the sender depending on whether it's possible to redo.

FXUndoList::ID_REDO_ALL

Message identifier for the “redo all” method. FXUndoList handles both the SEL_COMMAND and SEL_UPDATE messages for this message identifier.

FXUndoList::ID_CLEAR

Message identifier for the “clear” method. FXUndoList handles both the SEL_COMMAND and SEL_UPDATE messages for this message identifier.

FXUndoList::ID_REVERT

Message identifier for the “revert” method. FXUndoList handles both the SEL_COMMAND and SEL_UPDATE messages for this message identifier.

Constants

ID_LAST

Public Class Methods

new() click to toggle source

Returns an initialized FXUndoList instance.

Calls superclass method Fox::FXObject::new
# File lib/fox16/undolist.rb, line 94
def initialize
  # Be sure to call base class initialize
  super

  # Set up the message map for this instance
  FXMAPFUNC(SEL_COMMAND, ID_CLEAR,    "onCmdClear")
  FXMAPFUNC(SEL_UPDATE,  ID_CLEAR,    "onUpdClear")
  FXMAPFUNC(SEL_COMMAND, ID_REVERT,   "onCmdRevert")
  FXMAPFUNC(SEL_UPDATE,  ID_REVERT,   "onUpdRevert")
  FXMAPFUNC(SEL_COMMAND, ID_UNDO,     "onCmdUndo")
  FXMAPFUNC(SEL_UPDATE,  ID_UNDO,     "onUpdUndo")
  FXMAPFUNC(SEL_COMMAND, ID_REDO,     "onCmdRedo")
  FXMAPFUNC(SEL_UPDATE,  ID_REDO,     "onUpdRedo")
  FXMAPFUNC(SEL_COMMAND, ID_UNDO_ALL, "onCmdUndoAll")
  FXMAPFUNC(SEL_UPDATE,  ID_UNDO_ALL, "onUpdUndo")
  FXMAPFUNC(SEL_COMMAND, ID_REDO_ALL, "onCmdRedoAll")
  FXMAPFUNC(SEL_UPDATE,  ID_REDO_ALL, "onUpdRedo")

  # Instance variables
  @undolist = []
  @redolist = []
  @marker = nil
  @size = 0
end

Public Instance Methods

add(command, doit=false) click to toggle source

Add new command (an FXCommand instance) to the list. If doit is true, the command is also executed.

# File lib/fox16/undolist.rb, line 133
def add(command, doit=false)
  # Cut redo list
  cut

  # No command given?
  return true if command.nil?

  # Add it to the end of the undo list
  @undolist.push(command)

  # Execute it right now?
  command.redo if doit

  # Update size
  @size += command.size     # measured after redo

  # Update the mark distance
  @marker = @marker + 1 unless @marker.nil?

  # Done
  return true
end
canRedo?() click to toggle source

Return true if we can still redo some commands (i.e. the redo list is not empty).

# File lib/fox16/undolist.rb, line 224
def canRedo?
  (@redolist.empty? == false)
end
canRevert?() click to toggle source

Return true if there is a previously marked state that we can revert to.

# File lib/fox16/undolist.rb, line 232
def canRevert?
  (@marker != nil) && (@marker != 0)
end
canUndo?() click to toggle source

Return true if we can still undo some commands (i.e. the undo list is not empty).

# File lib/fox16/undolist.rb, line 216
def canUndo?
  (@undolist.empty? == false)
end
clear() click to toggle source

Clear the list

# File lib/fox16/undolist.rb, line 284
def clear
  @undolist.clear
  @redolist.clear
  @marker = nil
  @size = 0
end
current() click to toggle source

Returns the current undo command.

# File lib/fox16/undolist.rb, line 239
def current
  @undolist.last
end
cut() click to toggle source

Cut the redo list

# File lib/fox16/undolist.rb, line 122
def cut
  @redolist.clear
  unless @marker.nil?
    @marker = nil if @marker < 0
  end
end
mark() click to toggle source

Mark current state

# File lib/fox16/undolist.rb, line 322
def mark
  @marker = 0
end
marked?() click to toggle source

Return true if the undo list is marked.

# File lib/fox16/undolist.rb, line 336
def marked?
  @marker == 0
end
redo() click to toggle source

Redo next command

# File lib/fox16/undolist.rb, line 174
def redo
  unless @redolist.empty?
    command = @redolist.pop
    command.redo
    @undolist.push(command)
    @size += command.size
    @marker = @marker + 1 unless @marker.nil?
    return true
  end
  return false
end
redoAll() click to toggle source

Redo all commands

# File lib/fox16/undolist.rb, line 196
def redoAll
  redo while canRedo?
end
redoName() click to toggle source

Return the name of the first available redo command. If no redo command is available, returns nil.

# File lib/fox16/undolist.rb, line 259
def redoName
  if canRedo?
    @redolist.last.redoName
  else
    nil
  end
end
revert() click to toggle source

Revert to marked

# File lib/fox16/undolist.rb, line 203
def revert
  unless @marker.nil?
    undo while (@marker > 0)
    redo while (@marker < 0)
    return true
  end
  return false
end
trimCount(nc) click to toggle source

Trim undo list down to at most nc commands.

# File lib/fox16/undolist.rb, line 294
def trimCount(nc)
  if @undolist.size > nc
    numRemoved = @undolist.size - nc
    @undolist[0, numRemoved].each { |command| @size -= command.size }
    @undolist[0, numRemoved] = nil
    @marker = nil if (@marker != nil && @marker > @undolist.size)
  end
end
trimSize(sz) click to toggle source

Trim undo list down to at most size.

# File lib/fox16/undolist.rb, line 306
def trimSize(sz)
  if @size > sz
    s = 0
    @undolist.reverse.each_index { |i|
      j = @undolist.size - (i + 1)
      s += @undolist[j].size
      @undolist[j] = nil if (s > sz)
    }
    @undolist.compact!
    @marker = nil if (@marker != nil && @marker > @undolist.size)
  end
end
undo() click to toggle source

Undo last command.

# File lib/fox16/undolist.rb, line 159
def undo
  unless @undolist.empty?
    command = @undolist.pop
    @size -= command.size
    command.undo
    @redolist.push(command)
    @marker = @marker - 1 unless @marker.nil?
    return true
  end
  return false
end
undoAll() click to toggle source

Undo all commands

# File lib/fox16/undolist.rb, line 189
def undoAll
  undo while canUndo?
end
undoCount() click to toggle source

Returns the number of undo records.

# File lib/fox16/undolist.rb, line 270
def undoCount
  @undolist.size
end
undoName() click to toggle source

Return the name of the first available undo command. If no undo command is available, returns nil.

# File lib/fox16/undolist.rb, line 247
def undoName
  if canUndo?
    current.undoName
  else
    nil
  end
end
undoSize() click to toggle source

Returns the total size of undo information.

# File lib/fox16/undolist.rb, line 277
def undoSize
  @size
end
unmark() click to toggle source

Unmark undo list

# File lib/fox16/undolist.rb, line 329
def unmark
  @marker = nil
end