- Undocumented Matlab - https://undocumentedmatlab.com -

Programmatic shortcuts manipulation – part 1

Posted By Yair Altman On December 23, 2015 | 7 Comments

User-defined shortcuts can interactively be added to the Matlab Desktop to enable easy access to often-used scripts (e.g., clearing the console, running a certain program, initializing data etc.). Similarly, we can place shortcuts in the help browser to quickly access often-used pages. Unfortunately, both of these shortcut functionalities, like many other functionalities of the Matlab Desktop and related tools (Editor, Browser, Profiler etc.), have no documented programmatic access.
Such programmatic access is often useful. For example, a large company for which I consult is using centralized updates to users’ shortcuts, in order to manage and expose new features for all Matlab users from a central location. It is easy to send updates and manage a few users, but when your organization has dozens of Matlab users, centralized management becomes a necessity. It’s a pity that companies need to resort to external consultants and undocumented hacks to achieve this, but I’m not complaining since it keeps me occupied…

Shortcuts in Matlab R2012a and earlier
Shortcuts in Matlab R2012a and earlier

Shortcuts in Matlab R2012b and newer
Shortcuts in Matlab R2012b and newer


Today’s post will describe “regular” shortcuts – those that are simple clickable buttons. Next week I will show how we can extend this to incorporate other types of shortcut controls, as well as some advanced customizations.

The shortcuts.xml file

It turns out that the shortcults toolbar (on R2012a and earlier) or toolstrip group (on R2012b onward) is a reflection of the contents of the [prefdir ‘\shortcuts.xml’] file (depending on your version, the file might be named somewhat differently, i.e. shortcuts_2.xml). This file can be edited in any text editor, Matlab’s editor included. So a very easy way to programmatically affect the shortcuts is to update this file. Here is a sample of this file:



   My Shortcuts
   
      Help Browser Favorites
      
         
         Help icon
         helpview([docroot '/mapfiles/matlab_env.map'], 'matlabenvironment_desktop');
         true
      
   
   
      
      Help icon
      disp('No callback specified for this shortcut')
      true
   
   
      
      MATLAB icon
      web('undocumentedMatlab.com')
      true
   
   
      
      C:\Yair\program\icon.gif
      cd('C:\Yair\program'); myProgram(123);
      true
   
   ...

The file is only loaded once during Matlab startup, so any changes made to it will only take effect after Matlab restarts.

Updating the shortcuts in the current Matlab session

We can update the shortcuts directly, in the current Matlab session, using the builtin com.mathworks.mlwidgets.shortcuts.­ShortcutUtils class. This class has existed largely unchanged for numerous releases (at least as far back as R2008b).
For example, to add a new shortcut to the toolbar:

name = 'My New Shortcut';
cbstr = 'disp(''My New Shortcut'')';  % will be eval'ed when clicked
iconfile = 'c:\path\to\icon.gif';  % default icon if it is not found
isEditable = 'true';
scUtils = com.mathworks.mlwidgets.shortcuts.ShortcutUtils;
category = scUtils.getDefaultToolbarCategoryName;
scUtils.addShortcutToBottom(name,cbstr,iconfile,category,isEditable);

The shortcut’s icon can either be set to a specific icon filepath (e.g., ‘C:\Yair\program\icon.jpg’), or to one of the predefined names: ‘Help icon’, ‘Standard icon’, ‘MATLAB icon’ or ‘Simulink icon’. The editable parameter does not seem to have a visible effect that I could see.
The category name can either be set to the default name using scUtils.getDefaultToolbarCategoryName (‘Shortcuts’ on English-based Matlab R2012b onward), or it can be set to any other name (e.g., ‘My programs’). To add a shortcut to the Help Browser (also known as a “Favorite”), simply set the category to scUtils.getDefaultHelpCategoryName (=’Help Browser Favorites’ on English-based Matlab installations); to add the shortcut to the ‘Start’ button, set the category to ‘Shortcuts’. When you use a non-default category name on R2012a and earlier, you will only see the shortcuts via Matlab’s “Start” button (as seen in the screenshot below); on R2012b onward you will see it as a new category group within the Shortcuts toolstrip (as seen in the screenshot above). For example:

scUtils = com.mathworks.mlwidgets.shortcuts.ShortcutUtils;
scUtils.addShortcutToBottom('clear', 'clear; clc', 'Standard icon', 'Special commands', 'true');

Custom category in Matlab R2010a
Custom category in Matlab R2010a

To remove a shortcut, use the removeShortcut(category,shortcutName) method (note: this method does not complain if the specified shortcut does not exist):

scUtils.removeShortcut('Shortcuts', 'My New Shortcut');

The addShortcutToBottom() method does not override existing shortcuts. Therefore, to ensure that we don’t add duplicate shortcuts, we must first remove the possibly-existing shortcut using removeShortcut() before adding it. Since removeShortcut() does not complain if the specific shortcut is not found, we can safely use it without having to loop over all the existing shortcuts. Alternately, we could loop over all existing category shortcuts checking their label, and adding a new shortcut only if it is not already found, as follows:

scUtils = com.mathworks.mlwidgets.shortcuts.ShortcutUtils;
category = scUtils.getDefaultToolbarCategoryName;
scVector = scUtils.getShortcutsByCategory(category);
scArray = scVector.toArray;  % Java array
foundFlag = 0;
for scIdx = 1:length(scArray)
   scName = char(scArray(scIdx));
   if strcmp(scName, 'My New Shortcut')
      foundFlag = 1; break;
      % alternatively: scUtils.removeShortcut(category, scName);
   end
end
if ~foundFlag
   scUtils.addShortcutToBottom(scName, callbackString, iconString, category, 'true');
end

As noted above, we can add categories by simply specifying a new category name in the call to scUtils.addShortcutToBottom(). We can also add and remove categories directly, as follows (beware: when removing a category, it is removed together with all its contents):

scUtils.addNewCategory('category name');
scUtils.removeShortcut('category name', []);  % entire category will be deleted

Shortcut tools on the Matlab File Exchange

Following my advice on StackOverflow [1] back in 2010, Richie Cotton wrapped the code snippets above in a user-friendly utility (set of independent Matlab functions) that can now be found on the Matlab File Exchange [2] and on his blog [3]. Richie tested his toolbox on Matlab releases as old as R2008b, but the functionality may also work on even older releases.

Shortcuts panel embedded in Matlab GUI

Shortcuts are normally visible in the toolbar and the Matlab start menu (R2012a and earlier) or the Matlab Desktop’s toolstrip (R2012b onward). However, using com.mathworks.mlwidgets.shortcuts.ShortcutTreePanel, the schortcuts can also be displayed in any user GUI, complete with right-click context-menu:

jShortcuts = com.mathworks.mlwidgets.shortcuts.ShortcutTreePanel;
[jhShortcuts,hPanel] = javacomponent(jShortcuts, [10,10,300,200], gcf);

Shortcuts panel in Matlab figure GUI
Shortcuts panel in Matlab figure GUI

Stay tuned…

Next week I will expand the discussion of Matlab shortcuts with the following improvements:

  1. Displaying non-standard controls as shortcuts: checkboxes, drop-downs (combo-boxes) and toggle-buttons
  2. Customizing the shortcut tooltip (replacing the default tooltip that simply repeats the callback string)
  3. Customizing the shortcut callback (rather than using an eval-ed callback string)
  4. Enabling/disabling shortcuts in run-time

Merry Christmas everyone!

Categories: Desktop, High risk of breaking in future versions, Icons, Undocumented feature


7 Comments (Open | Close)

7 Comments To "Programmatic shortcuts manipulation – part 1"

#1 Comment By Andi On December 23, 2015 @ 18:33

Yair

Thank you for addressing the shortcut customization in MatLab.

The code to update the shortcuts during a session, which is discussed in your article, works very well in MatLab 2012a. However, it does not work reliably in MatLab 2015a, even though I tried to adapt it.

I have addressed this issue with Mathworks. The response was that they do not support this functionality.

I have also done some work, where I have tried to update the quick access toolbar, but again found, that is works very unreliably.

I am very interested in solutions for both issues, which work in MatLab 2015a.

Thanks, Andi

#2 Comment By Yair Altman On December 24, 2015 @ 00:04

@Andi – I am not sure what exactly is not working for you in R2015a – it works well for me up to and including R2016a. Try to add a short pause() before you update the shortcuts on startup, maybe this will help. If you would like me to look at your specific issue for a small consulting fee, then email me.

#3 Comment By Harry On July 21, 2020 @ 00:20

Andi, you are such a tease! There are questions dotted around the web (including on this page) of people asking how to change the Quick-Access Toolbar programmatically, and getting no answer, and here you are saying that you’ve (sort of) done it! Saying it “works very unreliably” implies that it has worked for you at least once; maybe the change didn’t stick, maybe sometimes you get the dreaded red text at the command line and sometimes not – but it sounds like you were at least on the right path. I know that this is a massive long-shot given your post is almost five years old – but, if my post triggers an email to you – please could you tell us how you were updating the Quick-Access Toolbar?

I know that versions after 2018a now use favourites. Adding favourites to the Quick-Access Toolbar programatically is easy, using the .setIsOnQuickToolBar method of the com.mathworks.mlwidgets.favoritecommands.FavoriteCommandProperties class. However, I am still interested in how to programatically get shortcuts onto the Quick-Access Toolbar in 2017b and earlier. Thus far, I have a partial solution by editing the MATLABQuickAccess.xml file (thanks to Yair and this page for the inspiration for that idea…), but that file is only read at startup so you have to ask the user to restart MATLAB to see your changes, which is less than ideal. And if they don’t restart straight away, they could do things in MATLAB that undo the changes you’ve made to the xml file.

#4 Comment By Thierry On January 7, 2016 @ 15:20

Hi Yair.
Thanks for this post!
Do you know a way to programmatically assign the created shortcut to the Quick Access Toolbar?
(This way the shortcuts are also visible on the MATLAB Editor.)
Many thanks.

#5 Comment By Julien On November 22, 2018 @ 19:29

Thanks a lot for these tips, it works very well on Matlab 2016b.
It seems since the R2018a, shortcuts have disappeared to be replaced by favorites commands… do you have any idea on how to manipulate favorites programatically ?

I saw this on Matlab Central : [10]
But there is no solution.

#6 Comment By michel bertrand On March 17, 2019 @ 20:26

There is a solution to create categories and get favorites, code, etc posted on nov 27.
I am playing with these ideas, and in the process of re-writing the Matlab code I wrote and maintained for more than ten years (following a Yair’suggestions, also many years ago) to save shortcuts when exiting Matlab so as to be able to restore those as they were on a specific day when exiting Matlab; a kind of laymen time machine for shortcuts.

I found scUtils still “works” in Matlab2018b, but it appears to process something which is distinct from the Favorites that were created when I first launched Maltab2018.
My first launching of Matlab2018b a few weeks ago followed a Matlab session ending under Matlab 2017b. On its first opening, Matlab2018b did some clean up on shortcuts it found and created their Favorites counterpart using the same name and the same code.
In my current usage of 2018b, scUtils can still see the old shortcuts and it will give shortcut names and code line exactly the same as those appearing under Favorites, provided those Favorites haven’t been modified with the favorite editor; after a favorite is edited, rerunning scUtils will show the original code, unchanged.

#7 Comment By Mike On July 3, 2020 @ 21:24

Yair,

It may be July 2020 but at my company we are still using R2013b! This article was instrumental in helping me to accomplish my work.

Thanks!
Mike


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/programmatic-shortcuts-manipulation-part-1

URLs in this post:

[1] my advice on StackOverflow: http://stackoverflow.com/questions/2802233/programmatically-configure-matlab

[2] Matlab File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/27567-shortcut-tools

[3] his blog: http://4dpiecharts.com/2010/08/23/a-shortcut-to-success/

[4] Programmatic shortcuts manipulation – part 2 : https://undocumentedmatlab.com/articles/programmatic-shortcuts-manipulation-part-2

[5] Command Window text manipulation : https://undocumentedmatlab.com/articles/command-window-text-manipulation

[6] Plot-type selection components : https://undocumentedmatlab.com/articles/plot-type-selection-components

[7] R2009b keyboard bindings : https://undocumentedmatlab.com/articles/r2009b-keyboard-bindings

[8] Customizing Workspace context-menu : https://undocumentedmatlab.com/articles/customizing-workspace-context-menu

[9] Variables Editor scrolling : https://undocumentedmatlab.com/articles/variables-editor-scrolling

[10] : https://www.mathworks.com/matlabcentral/answers/411846-how-to-create-favorites-by-code-command-window

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.