Friday, June 5, 2009

LabVIEW Scripting Tip #2: Supporting Undo

One of the great things about LabVIEW Scripting is that we can implement tools that perform actions in the LabVIEW editor. There are already several utilities posted on LAVA along these lines, along with the hopefully-soon-to-be-released JKI Right-Click Framework. Not to mention current and future shipping LabVIEW features.

In order to give your scripting-based utility equal footing with built-in LabVIEW features, though, you need to make sure anything you do with scripting can be undone or redone by the user. Thankfully, there is support in scripting for setting up Undo/Redo transactions, as illustrated by this screenshot:



Here are some details on each of the methods shown in the screenshot:
  • Transaction.Begin Undo - Call this method before you start your scripting operation. The "Name" input is the text that you want users to see next to the Undo/Redo options in the Edit menu:











    After calling Begin Undo, you will do all the scripting code you need to do for whatever editor operation you are performing. While doing your scripting, you need to keep track of a boolean, or some sort of flag, indicating whether or not you actually want to complete the Undo transaction, so you can make a decision between the following two methods.
  • Transaction.End Undo - Did everything script ok? Assuming you didn't get any errors, and that your scripting code actually did change something on the target VI, you need to end your Undo transaction. This actually commits the scripting action to the target VI, and creates the Edit > Undo option in the menu with the Name you specified on Begin Undo.
  • Transaction.Fail - Did an error occur during your scripting? Or did your scripting code not actually change anything? If either of these is the case, you probably want to Fail the transaction. This means that the transaction is not committed to the target VI, and that no new Undo option is added to the Edit menu. Notice that in my screenshot, I do not wire the error up to the Transaction.Fail method. This is because, if an error occurred in my scripting, I still want the Fail method to execute so it cancels the transaction.
If you decide not to wrap your scripting operations with these transaction methods, there are two significant consequences. First, and most obvious, is that users will not be able to undo whatever scripting operation you have performed. Second, and more severe, is the fact that a scripting operation that is not wrapped with these transaction methods can clear the existing Undo stack of a VI. So if you are developing a first-class scripting utility with any sort of integration into the LabVIEW editor, make sure to take these simple steps to make your operations undoable/redoable.

4 comments:

  1. Hey Darren: Great article. It's really awesome to be able to discuss design patterns and tools for scripting. Regarding the JKI Right-Click Framework, one of its cool features is that it creates undo transactions for the plug-in operations so that developers don't need to worry about it when coding their plugins. Also, yes, JKI is working hard to wrap up the hopefully-soon-release of the Right-Click Framework. :)

    ReplyDelete
  2. There are some scripting properties like "MultiFrameStructure.VisibleFrame" that, IMO, shouldn't clear the existing Undo stack if they are called. The reason being is that when the user changes the visible frame in the IDE it is not an undoable action. So, it's odd that my editor tool will add a bunch of "Visible Frame Changed" undo transactions that the user will see (just so that I can preserve the undo stack of the VI)

    ReplyDelete
  3. I agree, it's inconsistent. Interactively changing the visible frame of a multi-frame structure doesn't put an entry on the undo stack, but it is a cosmetic change that is preserved when saving the VI. Interestingly, LabVIEW NXG also behaves this way. I'll start a discussion within LabVIEW R&D about how we might make this behavior more consistent.

    ReplyDelete
  4. Thanks, Darren! I appreciate you looking into this. It'll make a big difference for the user experience with edit-time helper tools.

    ReplyDelete