Jump to content

Implementing UNDO in my application UI.


Recommended Posts

So far the need occurred to me only in an application whose only undoable part was the assisted filling of a big table. Not being particularly sophisticated, I created a finite depth queue, which stored the last N states of that table. Each value change of that control - enqueue at opposite end a new state. Each call of the user menu 'Undo' - dequeue one value and Property/write Value it back to the table. The table itself was not so big that keeping a few historical copies of it in memory was tallying. As simple as that, but certainly not too representative of an application with a more complex state to be rolled back.

Link to comment

I also have not really had to implement undo for a sophisticated application. I have implemented "Restore Ro Default" and limited undo for settings,  configurations and such but have not been called upon for the kinds of undo required for things like drawing. I would imagine the same method could be used though.

I used the SQlite Savepoints for configurations and a default table which could be copied to the main table for "Restore to Default". The latter is an example library in the SQLite Toolkit for LabVIEW. Other similar operations can also be realised like restoring the state of the UI after exiting (form position, controls etc) but that's not really what you are asking here; just an indication of the usefulness of these approaches.

 

Addendum: There is a description of a method for Undo/Redo using SQLite triggers. Automatic Undo/Redo Using SQLite

They over complicated it by doing it in an "Object Oriented" fashion but I might use something similar for the redo while keeping the savepoint method for undo.

Edited by ShaunR
Link to comment

I implemented undo several times in my applications, mainly because I usually do editors.

I did it many ways, usually I check if the data/state changes (after the event structure) and push the data on a FIFO. For most of the time, simply putting all raw data was sufficient. Once (in C win32, not in Labview) I had too much data, so I had to use "command pattern", which means only commands with relevant parameters were pushed on the undo stack and the initial raw data was saved with the undo "object".
It had limited depth (depending on available memory), so the initial datas had to be updated if memory would run out. So the oldest command was performed on the initial data.
Of course in some cases the "parameters" of the commands were bigger data (like paste from clipboard), but it worked pretty well. One caveat: it was quite slow to undo, since all the commands in the command stack had to be sequentially applied on the initial data. If all commands are reverseable without computing errors (which pretty much rules out math operations and delete and such), the stack could re reversely traversed so no slowdown.

Back to labview: I can't really exmplain after all these years what's happening, so I'll just post the code of "the most sophisticated" undo I did. It pushes the complete state to the undo stack, because the data was small (sequence editor). The word "manager" in the name is a bad sign, but here it goes.
Note1: it's implememted in a way that selection changes are not added to the stack, only the last one, or I don't really remember. So you can just ignore the "overwrite" case.
Note2: it's an old code from my newbie times. It fails the single responsibility principle badly,  I think both "undo stack" and "stack index" should be action enginified, the outputs besides "output data" is only for optimizing recalculation of data so simply ignore them.

EDIT: I've found a later implementation, so changed the vi. The data change check is outside the vi.

 

 

pic_man_undo_manager.vi

Edited by Lipko
Link to comment
  • 9 months later...

I'd just pop up a dialog with a "Please contact our company's support channel and Idea Exchange forum to discuss or request implementation of this feature. Reminder: access to future improvements of our software is reserved to continuing subscribers. Other cheaper and more powerful alternatives may be available".

  • Haha 2
Link to comment
1 hour ago, Michael Aivaliotis said:

Having a bad day? 😀

Just reflecting on what some not-to-be-named companies have accustomed us with...

But in answer to your question, if you have irreversible actions taking places (that would be the case in the type of stuff I do, which is mostly computational when it is not DAQ - I don't suppose you want to undo drilling or cutting physical parts 🙂, clearly you need to store intermediates states to be able to backtrack to those and since juggling between different cases might be tricky. this might be your best approach...

And since even the not-to-be-named company has been unable to find a satisfactory solution despite their elite team of programmers after 20 years (not mentioning that there is no undo in tons of locations in the IDE), this is clearly not a trivial problem. But that might be one sentence too much. Hold on, Musk hasn't bought that site yet, has it?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.