TheBigUndo v1.0.4.3
TheBigUndo is a module that allows RealStudio developers to add undo/redo
functionality to their projects with little effort yet can be fully customized to provide
undos for difficult situations.
To Add TheBigUndo to a project, just drag the module and the CustomUndo Interface
to the project pane and add TheBigUndo.init to the app's open event. This will
provide basic undo functions to most controls.
Undos are created via an automatic check loop by default, but can also be manually
triggered. Undo check timing can be adjusted or the undo loop can be prevented from
running at all by passing -1 to initUndo or by setting UndoPeriod to -1.
Class extensions provide simple access to features like control.UpdateUndoStateNow
which can be used for manual updates, or to make the state current before a call to
Windows and Custom controls can be given undo functionality by utilizing
the CustomUndo class interface
Thanks for trying TheBigUndo!
This software is distributed as-is. Use of this software is without warranty, written
or implied. This software and it's source code are the exclusive intellectual property
of piDog Software.
Purchase of a license allows you to include TheBigUndo and TheBigUndoPreferencesWindow
in your projects and products. A Single User License means one user under one licensed copy of
RealStudio at one time. Multi-User licenses are also available.
Any attempt to reverse-engineer TheBigUndo, attempt to circumvent encryption or licensing or sharing of license keys
will be considered a violation of the license agreement and may be a violation of copyright
laws. piDog Software reserves the right to terminate a violator's license(s) and to prosecute any
such violation.
Copyright piDog Software 2012-2015
License Agreement
TheBigUndo may be licensed for use and distribution in applications built using Xojo by Xojo inc.
A license allows use by the registered developer only. Additional licenses must be purchased for each
additional developer.
Any attempt to break or bypass TheBigUndo's encryption will be a violation of this agreement.
Any attempt to reverse engineer TheBigUndo will be a violation of this agreement.
Sharing, selling or any other form of distributing a license key, intentional or accidental will be
a violation of this agreement.
Any violation of this agreement will result in the termination of the licensee's right to include TheBigUndo in
any applications.
Copyright 2012-2015 piDog Software.
Release Notes
Updated for Xojo 2014r3
Removed external images from demo app.
Fixed a bug when building an app
Fixed a bug causing a KeyNotFoundException when RadioButtons were placed on a ContainerControl
Added Undo and Redo methods to the module to allow manually calling Undo/Redo actions from code
Added TheBigUndo_StateChangedNotifier interface to allow creation of custom controls to invoke undos
Fixed a possible KeyNotFoundException related to ContainerControls
ContainerControls are now detected automatically!
Listbox now supported in window.xml
ListBox RowPicture now supported in undo/redo and window.xml
Updated Documentation and Demo.
Now Xojo compaible!
Fixed a bug where undos in Styled TextAreas could become garbled if styled text was copied and pasted repeatedly.
Fixed GTK lib calls to work under Ubuntu 12.10 and other current linux flavors
Minor internal efficiency improvements
If UndosAreManual is set for a control, the control is now checked before the Undo Menu is enabled
Added UndoSetsContentsChangedFlag extension to Window Class
Added a Cocoa workaround for sliders to handle setting a value of 0 in an undo/redo
Made some improvements in listbox behavior where an object in a tag is an unknown type (ie plugin class) it is ignored
Listbox checkboxes are now undoable.
Dictionaries and Tag (celltag, rowtag) Picture values now more efficient.
Fixed some issues with the demo project file
Fixed a bug with UndoInFrontWindowOnly that prevented undos in non-document windows
Now correctly ignores all non-undoable controls
Made the Module an internal item in the demo project
Rearranged Modules and supporting items items so they can be used as external items.
Fixed a bug causing container controls not to be checked correctly.
Fixed a bug causing demo to crash on Linux when viewing methods/properties
Fixed a Cocoa bug in TextAreas
Renamed internal calls to avoid conflicts with globals in other modules
Redesigned Styled TextArea Undo handling. CPU usage is now negligible under normal conditions.
Win32 TextArea's no longer "jump around" during undo's
Removed multi-threaded operations to avoid rare, yet possible, crashes.
Updated documentation accordingly.
Fixed UpdateUndoStateNow to clear any pending redo's
Fixed a glitch in the contacts list demo
Moved everything into one Module for ease of use.
CustomUndo interface is now TheBigUndo_CustomUndo interface.
Added documentation to methods inside TheBigUndo module.
Fixed a possible Cocoa crashing bug with control.handle.
TheBigUndo.Init now blocks from being called from multiple locations.
RadioButtons now undo as groups rather than individual controls.
Now handles multibyte characters properly.
TextAreas and TextFields now select text added in an undo or redo action.
Added AddUndoMenuToMenuBar(theMenuBar) for use with multiple menubar apps.
Added SetsContentChangedFlags property to control setting the ContentsChanged flag for windows with available Undo's
Added an XML extension to the window class. Allows getting and setting window state to and from XML.
Added a ClearUndos flag to XML setter to allow users to back out of a "Default Settings" action. ie Preferences Windows.
Added "View"/"Window as XML" menu to the demo project.
Added Window.SimpleDictionary for easy (and multithreaded) access to TheBigUndo_PreferenceWindow values.
Added an internal Cocoa Wrapper class to eliminate some memory leaks.
Added default ListBox Undo handling.
ContactsDemo now uses default Listbox Undo's.
Added Window.SavedState property to allow specifying a state where a window's ContentChanged will be false
CustomUndo now works again.
Fixed a situation that could cause container controls to not record undo's
Removes all references to controls in closed windows
Now completely ignores all non-undoable controls
Demo now sets IgnoreUndos in the main demo window
Demo now sets MonitorFrontWindowOnly
Demo now calls PauseUndoChecking on deactivate and ResumeUndoChecking on activate
Added a throttle to increase checking delay in cpu heavy controls
Calling Window.UpdateUndoStateNow now works as intended again
Improved initial state capture for newly opened windows
Reworked some other state tracking during undo's for more reliability and speed
Reduced CPU usage some more.
Minor edits to documentation.
Updated documentation for CustomUndo Interface.
Now ignores textfields where password=true
Fixed a delay when calling control.DeleteUndos()
Changed CustomUndo Function names to begin with CustomUndo_
Fixed a crashing bug under Cocoa. controlMacControlHandleGetter
Added a more in depth Custom TextArea example.
Initial beta release
An XSL Style for readable XML.
Sub AddUndoMenuToMenuBar(TheMenuBar As MenuBar)
Adds Undo and Redo MenuItems to a MenuBar
Sub DeleteRedos()
Clears all recorded redo actions
Sub DeleteRedos(extends c As control)
Clears redo's for a given control
Sub DeleteRedos(extends w As Window)
Clears recorded redo's for a given window
Sub DeleteUndos()
Clears all recorded Undo actions
Sub DeleteUndos(extends c As Control)
Clears all Undo's for a gven control
Sub DeleteUndos(extends w As Window)
Clears all Undo's for a given window
Function GetPreferencesDoc(optional PrefsFile as FolderItem, optional Key As String) As XmlDocument
This Method will return a previously saved XmlDocument saved to the user's preferences
Function HasUndos(extends c As Control) As Boolean
Returns true if there are Undo's for the given control
Sub IgnoreUndos(extends c As control,assigns state As Boolean)
Stops/Starts checking for undo's for the given control
Sub IgnoreUndos(extends w As window, assigns state As Boolean)
Stops/Starts checking for undo's for the given window
Sub Init(undoPeriod As integer=1000)
Starts up the undo module. Period is 1/1000ths of a second for the undo loop to run. Pass -1 to trigger all undo testing manually.
Sub MaximumUndos(extends w As window,Maximum As Integer)
Sets the maximum number of undo's to be recorded for a given window.
Sub MaximumUndos(assigns max As Integer)
Sets the maximum number of undo actions to be recorded
Sub MaximumUndos(Extends c As control, assigns Maximum As integer)
Sets the maximum number of undo's to be recorded for a given control.
Sub PauseUndoChecking()
Stops the undo testing loop after allowing the background thread to finish any current task. Useful when performing other cpu intensive tasks.
Sub Redo()
Invokes the next available Redo
Function Register(Name As string, ExpirationDate As string, SerialNumber as string,optional CopyNumber As Integer=1) As Boolean
A method to enter registration info and remove the registration warning message in compiled apps.
Sub ResumeUndoChecking()
Resumes undo testing after a call to PauseUndoChecking
Sub SavedState(extends w As Window, assigns xmldoc As XmlDocument)
Sets an XMLDocument as received from then XML property as the currently
saved state of the window so that the window's ContentChanged flag can be
set when the current window state varies from the saved state.
Function SavedState(extends w As window) As XmlDocument
Gets the last XmlDocument set via Window.SavedState=XMLDocument
Sub SetPreferencesDoc(value As XmlDocument, optional PrefsFIle As FolderItem, optional Key As String)
This Method will save an XmlDocument to the user's preferences
Function SimpleDictionary(extends w As Window) As Dictionary
This Function returns a Dictionary containing the basic values of basic controls. CustomUndos and ContainerControls are excluded.
Included for use in TheBigUndo_PreferenceWindow example, and similar uses.
Sub Undo()
Invokes the next available Undo
Sub UndosAreManual(Extends c As Control,Assigns value As Boolean)
Set this to true to exclude a control from the undo testing loop.
Sub UndosAreManual(extends w As window,assigns value As Boolean)
Set this to true to exclude a window from the undo testing loop.
Function UndosAreManual(extends c As Control) As Boolean
Set this to true to exclude a control from the undo testing loop.
Function UndosAreManual(extends w As Window) As Boolean
Set this to true to exclude a window from the undo testing loop.
Function UndoSetsContentsChangedFlag(extends w As Window) As Boolean
Gets whether available undos cause the changed flag to be set for the window.
Sub UndoSetsContentsChangedFlag(extends w As window,assigns value As Boolean)
Sets whether available undos cause the changed flag to be set for the window.
Sub UndoStateChanged(extends c As Control, assigns value As Boolean)
Passing True will tag the Control for testing on the next loop when UndosAreManual has been set.
Sub UndoStateChanged(extends w As window, assigns value As Boolean)
Passing True will tag the window for testing on the next loop when UndosAreManual has been set.
Sub UpdateUndoStateNow()
Call to start a new run of the undo testing loop.
Sub UpdateUndoStateNow(extends c As control)
Will run the undo tests on a given Control.
Sub UpdateUndoStateNow(extends w As Window,IncludeManualUndos As Boolean=true)
Will run the undo tests on a given Window.
Sub XML(extends w as window,ClearUndos as Boolean=false,assigns XML As XmlDocument)
Sets the state of a window from an XmlDocument as return by the XML getter Function.
Use XmlDocument.Transform(XSLReadable) for an easy to view Document.
Use CUndos in the case of a preferences window setting to defalt setting or the like.
MyWindow.XML=SavedDoc or MyWindow.XML(false)=SavedDoc
Function XML(extends w As Window) As XmlDocument
Gets the state of a window as XML.
For CustomUndo controls, pictures are Base64 Encoded PNG's at 100% quality setting.
Array's and Dictionaries are also supported
StyledTextAreas are stored as Base64 Encoded RTF
MemoryBlocks are stored as Base64 Encoded Strings
To add additional tags for use by your app add tags at the top level with a name other than "Document"
Sub XMLIgnore(Extends c As Control,assigns value As Boolean)
Sets a control to be ignored (or not ignored) when getting a window's state as XML
MonitorFrontWindowOnly As Boolean
This property determines whether TheBigUndo will track all windows, or exclusively track the frontmost document window to save cpu cycles.
Default is true
PreferencesDoc As XmlDocument
Use this property to set and get and XmlDocument representing your
app's Preference Window.
Default locations are
folder's visible property is set to false
saved as an entry in ~/Library/Preferences/[app identifier].plist
with the key "PreferenceWindowSettings"
Be sure to set your app identifier or nothing will be saved!
You can override these by using GetPreferencesDoc and SetPreferencesDoc and passing a FolderItem(Win32/Linux) or Key String(MacOS),
this also allows for multiple preference windows.
SetsContentsChangedFlags As Boolean
UndoInFrontWindowOnly As Boolean
Prevents TheBigUndo from performing undos in windows that are not in focus.
Pending Undos will be available when said window gains focus.
Default is true.
UndoPeriod As Integer
This property sets the frequency of undo checking. Value is 1/1000th of a second.
Default is 1000
The CustomUndo interface can be implemented by any control or window.
This interface overrides the default checking and undo implementation.
CustomUndo is mostly intended for controls that do not have standardized data (ie. Listboxes)
This could also be useful for custom controls such as a color chooser or a drawing control.
1) Add CustomUndo to the control or window's interfaces.
2) CustomUndo_GetCurrentState should return a dictionary representing the current state of the control or window.
This will be a dictionary with any number of key/value pairs representing any arbitrary data including pictures.
3) CustomUndo_CheckForStateChange will be passed the most recent state object to be compared with the current state.
if the state has changed return a dictionary describing the change(s), otherwise return nil.
Include an "Undo Type" key with a label to be shown in the UndoMenuItem and RedoMenuItem if you like.
4) CustomUndo_SetCurrentState will be passed the last Dictionary returned by CustomUndo_CheckForStateChange when the user
selects "Undo" from the edit menu.
5) After the undo has been executed, CustomUndo_CheckForStateChange will be called again to obtain the redo dictionary.
if redo is impossible, return nil.
When using this module with controls that use large data, such as an image editor, either only the changed
portion of the image should be returned or the undo levels should be limited to a reasonable amount by setting
Function CustomUndo_CheckForStateChange(LastState As Dictionary,isRedo As Boolean=false) As Dictionary
Allows creation of a dictionary describing changes in state. Return nil if no changes were found.
Function CustomUndo_GetCurrentState() As dictionary
Should return a dictionary desribing the current state of the implementor.
Function CustomUndo_SetCurrentState(StateDictionary As Dictionary,isRedo As Boolean=false) As Boolean
Called when an undo or redo is invoked. StateDictionary is the dictionary returned from CheckForStateChanges
TheBigUndo_StateChangedNotifier is an interface that can be implemented by any class.
The methods will be called with the text describing the Undo/Redo state and a boolean value to determine if there is an Undo/Redo available.
Sub TheBigUndo_RedoStateChanged(RedoText As String, Active As Boolean)
Called when the Redo state has changed. RedoText is the text the user should see, Active is whether a Redo is available.
Sub TheBigUndo_UndoStateChanged(UndoText As String, Active As Boolean)
Called when the Undo state has changed. UndoText is the text the user should see, Active is whether an Undo is available.