Skip to main content
Inspiring
December 10, 2021
Question

Is there any way to suppress having a command added to the undo queue?

  • December 10, 2021
  • 3 replies
  • 779 views

I'm writing a script that needs to check if fonts are available. I'd like to do this live as the user types the font name (so that a relevant control only enables when the name corresponds to an available font), but the only way I can think of to do this involves adding a comp and a text layer to the project, then changing the layer's font and checking that the change actually took. The problem is this all gets added to the undo queue, and even if I put it in an undo group, if I'm checking this on every onChanging event for an EditText, this still floods the undo queue with dozens of pointless Undo entries.

 

I tried using

app.executeCommand(app.findMenuCommandId("Undo "+undoGroupName));

to remove the undo entries at each step, but this unfortunately causes the EditText to lose focus, which defeats the purpose.

 

I'm pretty sure there isn't any other way to pop an entry off the undo queue programmatically, but is there any way to avoid pushing entries onto it in the first place?

This topic has been closed for replies.

3 replies

ConstantinMaier
Inspiring
December 12, 2021

Not sure whether this would work in your circumstances but I've had a similar problem where I needed to avoid creating a bunch of undo groups. The solution was to close the current undo group and then create an undo group with an empty string. So like this:

 

app.beginUndoGroup("Main Function");
// Some Script Action
app.endUndoGroup();
app.beginUndoGroup("");
// Some other Action
app.endUndoGroup();

 

In the end, you're just left with the undo group "Main Function". However, there's a catch: Undoing the action works fine but when you want to redo it aftwards, you will end up at the first time you closed the undo group within the function, not the last time. But I think that's something you might be able to live with. 🙂

Mathias Moehl
Community Expert
Community Expert
December 11, 2021

I would love to hear a good solution for that, too.

I have a somewhat similar situation where I need to figure out all output module templates which are available on the machine. The scripting API exposes those as OutputModule.templates, but if your render queue is empty, you first need to create an entry in the render queue (and a comp that you can actually queue, if the project is empty...). So I also need to create various things that I want to undo in a clean way.

Unforuntately, I didn't find a good solution, yet, either.

app.executeCommand(app.findMenuCommandId("Undo "+undoGroupName));

 will also cause issues with foreign language versions of Ae.

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Inspiring
December 11, 2021

Good point about localization.

 

This is how I solved your problem for a script I wrote several years back. I grab the output module names from the preferences. (This is a member function of a bigger object, but hopefully it gets the idea across). This probably needs some localization-proofing, too.

 

 

 

function OMTemplateCollection()
    {
        var OMIndices = new Object();   //object for storing template indices keyed by name
        var ListIndices = new Object();
        var OMDefaultPrefsSection = "Output Module Preference Section v28";
        var OMDefaultPrefsKey = "Default OM Index";
        var OMStringsPrefSection = "Output Module Spec Strings Section v28";
        var OMStringsKeyPrefix = "Output Module Spec Strings Name ";
                    
        this.getOMTemplateNames = function()
            {
                var OMList = new Array();   //list -to-be of output module templates harvested from preferences
                var currentOMName;
                var hiddenPrefixRE = /_HIDDEN/;
                for(var i = 0; app.preferences.havePref(OMStringsPrefSection, OMStringsKeyPrefix+i, PREFType.PREF_Type_MACHINE_INDEPENDENT_OUTPUT); i++)
                {
                    currentOMName = app.preferences.getPrefAsString(OMStringsPrefSection, OMStringsKeyPrefix+i, PREFType.PREF_Type_MACHINE_INDEPENDENT_OUTPUT);
                    if(currentOMName.match(hiddenPrefixRE)==null) 
                    {
                        OMList.push(currentOMName);     //add to list of OM Templates
                        OMIndices[currentOMName] = i;                   //add index to list of indices
                        ListIndices[currentOMName] = OMList.length-1;   //store OMList indices for reverse lookup by OM name
                    }
                }
                return OMList;
            }
}

 

 

 

Sadly, this doesn't work for render templates.

Mathias Moehl
Community Expert
Community Expert
December 12, 2021

Oh, wow, that's amazing! Thank you so much for sharing this. Are render templates not stored in the prefs? Because as you seem to have guessed, I also need both...

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Mrtn Ritter
Participating Frequently
December 11, 2021

I'm wondering if your font-checking system actually work fluently. It sounds pretty complex. 

Do you know what font file you are checking for? Can't you search it in the font folder instead?

 

*Martin

Inspiring
December 11, 2021

I don't know what font the user will be looking for, and I need the postscript name of the font, which might not match the file name. What I'm doing does work, it just pollutes the undo queue.