Legato is an interpreted language, but even so, it performs quite quickly. Most scripts will execute within a second or so, even if it’s the script contains relatively complex HTML parsing or something similar. However, occasionally there are scripts that iterate over extremely large data sets, or work with file IO, or really do anything that can take a long time. If the script is just running, unless you put up some sort of a progress bar, it might look like the application has frozen to the user. Therefore, it’s really important to put up a progress bar to let the user know what’s going on with the script. I’ve put together a simple example script of a progress bar below, but let’s talk about how to use one first.
When you want to open a progress bar, you need to run the ProgressOpen function first. It can take up to three parameters: the title of the progress bar as a string, the time for which to show it, and the type of the progress bar as a predefined value. None of these are required, but the title should probably always be entered. There are a lot of flags for types of progress bars, but if no specific flag is provided, Legato will use the PW_BAR_DEFAULT value, which is just a normal progress bar. Check the documentation for more information about the different progress bar options.
Once you’ve opened a progress bar, you can set the text it displays. Every progress bar has two lines of text, and both are set through the ProgressSetStatus function. The function takes two or more parameters: the line number (either 1 or 2), the message, and any parameters required for the message to be completed. This operates in the same way you can pass additional parameters to functions like the FormatString function.
The actual progress bar itself can be changed by using the ProgressUpdate function. The progress can be updated by percentage or by item X of Y. If you want to just give it a flat percentage, simply pass a single integer with the number 0-100, representing the percentage to set the bar to. You can also pass it two integers representing item X of Y, and it will calculate how far the progress bar should be moved. The ProgressUpdate function also checks if the window has been cancelled since the last time the function has been executed. When you run the ProgressUpdate function, be sure to check the return value. If it’s ERROR_CANCEL, it means the user has opted to cancel the script, so you should handle it appropriately. Users can cancel by holding the ESC key for a second or by pressing the Cancel button on the progress window if you’ve chosen a progress bar type that has a cancel button. The default style does not include a cancel button.
Once your process is over, you can run the ProgressClose function. This, as the name implies, closes the progress bar. The progress bar should close by itself when the script naturally ends, but keep in mind if you have a progress bar open and the script encounters an error, then the script may not end naturally so it’s not going to get rid of the progress bar. It may just seem to the user like the script is still running, which would be quite confusing. So when using progress bars, always be sure to test your code to ensure that there are no unhandled error conditions possible in the script. Otherwise the bar might get stuck on the screen.
Here’s a short example script that demonstrates the progress bar’s basic functionality with these functions. It displays a progress bar, sets the status text, and loops twenty times to illustrate how to update the bar, check if it was cancelled, and change the text being displayed to show the current number.
#define COUNT 20
int main(){
int ix;
int rc;
ProgressOpen("Progress Window");
ProgressSetStatus("Beginning Process");
while(ix < COUNT){
rc = ProgressUpdate(ix,COUNT);
if (rc == ERROR_CANCEL){
MessageBox('x',"Operation Cancelled!");
ProgressClose();
return ERROR_NONE;
}
ProgressSetStatus(2,"Item %d of %d",ix,COUNT);
switch(ix){
case(5):
ProgressSetStatus("Really getting going now.");
break;
case(10):
ProgressSetStatus(1,"Halfway there.");
break;
case(15):
ProgressSetStatus(1,"Almost done!");
break;
}
Yield(true);
Sleep(300);
ix++;
}
ProgressClose();
return ERROR_NONE;
}
That’s the basics of using progress bars in Legato. No matter their style or complexity, they are a helpful, effective, and convenient way to keep users informed as to how long it’s taking a script to process an operation. That way, when something takes a little longer to execute, your users won’t be left hanging and wondering what’s going on behind the scenes.
Steven Horowitz has been working for Novaworks for over five years as a technical expert with a focus on EDGAR HTML and XBRL. Since the creation of the Legato language in 2015, Steven has been developing scripts to improve the GoFiler user experience. He is currently working toward a Bachelor of Sciences in Software Engineering at RIT and MCC. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato