In the past weeks we’ve explored multiple different scripts that hook into GoFiler menu functions. These have included creating custom table polishing scripts and inserting images directly into EDGAR HTML files. The capacity to hook custom functions into GoFiler through its menu functions is an extremely powerful aspect of Legato scripting. This week we’re going to examine a short script that can enumerate the menu functions in GoFiler. Our script prints the list of menu functions to both the log and to a CSV file, which provides more permanent storage for later reference.
string s1;
string code, m_name, r_name, desc;
string table[][4];
int id, ix;
AddMessage("Ribbon/Menu Dump:");
ix = 0;
table[ix][0] = "Function Code";
table[ix][1] = "Ribbon Name";
table[ix][2] = "Menu Name";
table[ix][3] = "Dscription";
code = MenuGetFunctionCode(ix);
while (code != "") {
id = MenuGetFunctionID(ix);
m_name = MenuGetMenuName(ix);
m_name = ConvertFromUnderlines(m_name);
r_name = MenuGetRibbonName(ix);
desc = MenuGetDescription(ix);
desc = ReplaceInString(desc, "\r", " ");
AddMessage("%4d %5d %-48s %-32s %-32s :: %s", ix, id, code, m_name, r_name, desc);
ix++;
table[ix][0] = code;
table[ix][1] = r_name;
table[ix][2] = m_name;
table[ix][3] = desc;
code = MenuGetFunctionCode(ix);
}
s1 = GetScriptFolder() + "Menu Dump.csv";
CSVWriteTable(table, s1);
Our script begins by declaring some variables we’ll need. In particular, we’re using a two dimensional string array, which we’ve named table, to contain our dump of the menu function names and IDs. Each menu function will have its numeric ID, its name, the name of its ribbon, the name of its menu, and its description. Note that the numeric ID may be essential for subsequent use. Other SDK functions, such as the MenuSetHook function, use the menu function ID to specify which menu function upon which to act. No two menu functions can share the same ID. As discussed in previous blogs, it’s a good idea to check to make sure any menu function you are adding or with which you are working has an unique ID. It’s also important to note that menu function IDs may not be held constant between application releases, so they should never be permanently coded into a script. Use the string name of the function to retrieve its unique numeric ID each time.
After declaring our variables, we initialize our counting variable and place titles in our first item of our array. Now we can retrieve our first menu function code by using the SDK function MenuGetFunctionCode.
ix = 0;
table[ix][0] = "Function Code";
table[ix][1] = "Ribbon Name";
table[ix][2] = "Menu Name";
table[ix][3] = "Description";
code = MenuGetFunctionCode(ix);
Now we enter a while loop that will continue so long as we can retrieve a menu function code. Once that returns with an empty string, we exit our loop. Inside the loop, we use the MenuGetFunctionID SDK function and we pass it our counting variable. This returns the numeric menu function ID.
while (code != "") {
id = MenuGetFunctionID(ix);
m_name = MenuGetMenuName(ix);
m_name = ConvertFromUnderlines(m_name);
r_name = MenuGetRibbonName(ix);
desc = MenuGetDescription(ix);
desc = ReplaceInString(desc, "\r", " ");
We then employ a bunch of other SDK functions to retrieve more information about this menu function, and we store it in our strings. This includes the menu function’s parent menu name, parent ribbon name, and its description. We use a couple functions to clean up our description and name for display.
After we have gathered our information, we can print it to the log. We can also increment our counting variable.
AddMessage("%4d %5d %-48s %-32s %-32s :: %s", ix, id, code, m_name, r_name, desc);
ix++;
We can also store our information into a string table. Note that because we have our headers in the table above, we need to increment our counter before we store the information at a particular position. After that, we can get our next menu function via the MenuGetFunctionCode SDK function again and loop around. If there are no further menu functions to retrieve, this will return an empty string, and we’ll finish the loop.
table[ix][0] = code;
table[ix][1] = r_name;
table[ix][2] = m_name;
table[ix][3] = desc;
code = MenuGetFunctionCode(ix);
}
Finally, we write our string table of menu function IDs and their properties out to a handy CSV file (which can be located anywhere, though in this case we’re placing it in the same folder as our script).
s1 = GetScriptFolder() + "Menu Dump.csv";
CSVWriteTable(table, s1);
The output in the log after running our script would appear something like this:
Ribbon/Menu Dump:
0 10200 COLLABORATE_POPUP Collaborate Popup Collaborate Popup :: Collaborate Functions
1 10201 COLLABORATE_FILE_OPEN Open File Open File :: <B>Open File and Collaborate</B> Open file in collaborate mode to allow multiple users to access the file.
2 10210 COLLABORATE_CALENDAR_NEW New Event New Event :: <B>Manage Calendar</B> [TBD].
3 10211 COLLABORATE_CALENDAR Calendar Calendar :: <B>Manage Calendar</B> [TBD].
4 10221 COLLABORATE_NOTIFY_NEW New Notifications New :: <B>New Notification</B> Create a new notification for a Project event.
5 10222 COLLABORATE_NOTIFY_NEW_POPUP New Notify New Notify :: <B>New Notification</B> Click here for options as to where to create a new notification.
6 10223 COLLABORATE_NOTIFY_NEW_ENTERPRISE Enterprise Notify Enterprise :: <B>New Notification</B> Add a notification for Enterprise.
7 10224 COLLABORATE_NOTIFY_NEW_ENTRY Project Entry Notify Project Entry :: <B>New Notification</B> Add a notification for Project Entry.
8 10225 COLLABORATE_NOTIFY_NEW_PROJECT Project Notify Project :: <B>New Notification</B> Add a notification for Project.
9 10226 COLLABORATE_NOTIFY_NEW_USER User Notify User :: <B>New Notification</B> Add a notification for User.
10 10227 COLLABORATE_NOTIFY_LIST Notifications Notification List :: <B>Manage Notifications</B> Manage notifications for a Project event.
You can see the menu functions are numbered, and their IDS, names, parent menus and ribbons, and descriptions are printed. Any functions that are labeled “TBD” in the description, as can be seen for COLLABORATE_CALENDAR and COLLABORATE_CALENDAR_NEW, may exist in the application, but they are roughly framed and not operational at this time. Again, these function IDs may change with application updates, so it’s not advisable to hard code the IDs into your scripts. Pass the name itself as a string, and use that to obtain the corresponding numeric ID as necessary. For example,
int = MenuFindFunctionID("COLLABORATE_POPUP");
This is a useful script to enumerate all of the menu functions in GoFiler. Next week, we’ll examine how to hook a custom function into a slew of GoFiler menu functions so we can adjust EDGAR preferences automatically upon loading a project.
Maggie Gardner joined Novaworks in the summer of 2016 but has been working with Legato since its release in 2015. She has over ten years experience programming in SAS, PHP and C++. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato