[javascript] Two (plus) ways to add a menu icon to your script  SOLVED

Forum for the PDF-XChange Editor - Free and Licensed Versions

Moderators: Daniel - PDF-XChange, PDF-XChange Support, Vasyl - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

Post Reply
Mathew
User
Posts: 564
Joined: Thu Jun 19, 2014 7:30 pm

[javascript] Two (plus) ways to add a menu icon to your script  SOLVED

Post by Mathew »

If I have a script that I use a lot, I'll generally make it into a menu item, rather than paste it into the console all the time. It's a bit complicated the first time, but once I've got the basic code, I can copy and paste it with minor changes.

The first step, of course, is to have the script. To make the script work best with a menu item, it's important to have it as a function, so that the function call can be easily added to the menu item. For the purpose of this post, I'm going to use the script posted in another forum post: viewtopic.php?p=187589#p187589

The next step is to come up with an icon. Some things to think about when making the icon:
Image size: I usually make the icons 40 pixels x 40 pixels (only because I used to do 20x20 and they were too small in some cases -- actually more common sizes are 32x32 or 48x48). The javascript specification says they must be 20 x 20, but PDF-XChange is pretty forgiving and will resize it. I have no idea how other pdf software reacts to larger icons. On PDF-XChange the larger size means it will show up better on the ribbon layout. To edit the icon, I use Gimp but you can use whatever software suits you.
Transparency: The icons look better if you make the background transparent rather than a color.
File format: I save the icon with the file format .png and make sure to not save the resolution:
image.png
Thievery: I'm no graphic artist so for the scripts I post on this forum I usually take screen captures of the icons in PDF-XChange and modify them - hopefully they don't sue me :mrgreen: There are many free icons posted online - the size 32x32 is much more common and would work fine - just be sure you're downloading an image .png ! :twisted:

Now you can add it to your script:
Method 1
Save the png file just created and load it when the menu loads. This uses a PDF-XChange added method viewtopic.php?p=112037#p112037
  1. I'd recommend saving the png into the same place as the script (ie the Javascripts folder in %APPDATA%\Tracker Software\PDFXEditor\3.0\Javascripts ). I'm saving it with filename 'SaveNC.png'.
  2. An easy way to get the correct spelling and path to use is the following function:

    Code: Select all

    app.getPath('user','javascript')
    It will output the path to the javascript folder so that if someone else uses the script, the path to application data is also correct for them. Add '/SaveNC.png' (your filename from the above) to the end.
    If you want to save into the application JavaScripts folder, you can get that with app.getPath('app','javascript');
  3. Add the code to the beginning of the script; I posted a pdf with all the information about both the base javascript functions, and the new PDF-XChange improvements here: viewtopic.php?p=184605#p184605
    For this I'm going to add it to a menu item, but adding a tool button is very similar

    Code: Select all

    app.addMenuItem( {
        cName: "saveNoAnnots",
        cUser: "Save Without Markup",
        oIcon: util.iconStreamFromImage( app.getPath('user','javascript') + '/SaveNC.png'),
        cParent: "File", // Adding to the file menu for the regular UI
        nPos: "cmd.saveTo", // Adding after the "Save To" option
        cRbParent: 'JS:QuickAccess', // add to the quick access bar on the ribbon
        nRbPos: "cmd.save", // put the icon after the 'save' button
        cEnable: "event.rc = (event.target != null);", // this line is optional: this disables to the tool button when there's no file active
        cExec: "saveWithoutAnnots(this, true);",
    });
    1. 'cName' The first line is a text string that is unique to your new menu item. I just make it something like the function name, but PDF-XChange have a hierachical naming method like 'cmd.document.export.toImages' that makes sense - i.e. one could use a 'domain' and then the tool name such as mathew.util.savena etc...
    2. 'cUser' The second line is the text that the user will see in the menu. For this example, because I'm adding it to the quickaccess toolbar, this text won't show, but will pop-up as a tooltip when the user hovers over the button.
    3. 'oIcon' The third line uses the PDF-XChange method util.iconStreamFromImage() to load the icon from the file directly.
    4. 'cParent' is the location it should appear in the regular UI (ie I'm adding it to the file menu)
    5. 'nPos' can be a number or a text string. To find the text strings, you'll need to run this in the console, and search through the somewhat cryptic output (code copied from PDF-XChange example file):

      Code: Select all

      /************************************************************************
      	To see the actual Classic/Ribbon UI structure you may use the 
      	following script:
      ************************************************************************/
      
      function FancyMenuList(m, nLevel) {
           var s = "";
           for (var i = 0; i < nLevel; i++) s += "  ";
           var n = m.cName;  
           if (n == "") n = "-----"
           console.println(s + n);
           if (m.oChildren != null)
               for (var i = 0; i < m.oChildren.length; i++)
                   FancyMenuList(m.oChildren[i], nLevel + 1);
      }
      var m = app.listMenuItems(); 	//to get list of items inside ClassicUI.MenuBar or inside the RibbonUI, 
                                      //  also the optional cName parameter can be used to get items-list of certain menu/toolbar/tab
      //var m = app.listToolbarButtons(); 	// to get list of items inside the Addon toolbar
      
      for (var i = 0; i < m.length; i++) FancyMenuList(m[i], 0);
    6. 'cRbParent' is the menu to show it in the ribbon menu. Here I'm adding it to the quick access bar
    7. 'nRbPos' is the position in the menu. Again it can be a number, or string.
    8. 'cExec' is the function you want to call, inside quotation marks (ie as a string). Watch out with this one: If your function call has a string as a paramenter, for example, you'll need to be careful about either using single quotes around double quotes (or the other way around) or escaping all the quotation marks inside.
    9. 'cHotkey' is an optional parameter (I didn't include it in the example above) that specifies a shortcut key for the menu item.
      • Examples: "Ctrl+Shift+K", "Ctrl+Alt+Num0", "Ctrl+Comma", "Ctrl+Tab", "Ctrl+Space", "Ctrl+Shift+K,C"
        Special key names: Ctrl, Shift, Alt, AltGr, Esc, Escape, Tab, Enter, Return, Break, Space, Sp, BackSpace, BkSp, ScrollLock, Ins, Insert, Del, Delete, PgUp, PageUp, PgDn, PageDown, Home, End, Up, Down, Left, Right, EqualSign, Minus, Subtract, Sub, NumPlus, NumAdd, NumMinus, NumSubtract, NumSub, Num0, Num1 ... Num9, NumMult, NumDiv, NumDec, Semicolon, Comma, Period, Dot, Slash, BackSlash, Tilde, LeftSqBrkt, RightSqBrkt, SingleQuote, F1, F2 ... F24
  4. Run this in the console to check that it works. If so, save the script with the suffix .js into the Javascripts folder and restart PDF-XChange. Now it acts almost the same as a built-in menu item.
Method 2
The second method is almost identical to the above method, and is the one I use. Instead of loading the image from a file, I encode the image data directly into the script.
  1. I made a pdf utility file to help getting the icon data and posted it here: viewtopic.php?t=42029
  2. Open the pdf tool and click on the button 'Pick Image File' to open the image file you created:
    image(1).png
  3. When you press 'OK' it should put the image data into the two form fields:
    The top form field is the straight image data. The second one includes a line of script that includes decompressing a compressed representation of the above data. I always use this. Copy it and paste into the beginning of the script file.
  4. The code is very similar to the first method with just the image data added at the beginning and the line oIcon referring to this icon data:

    Code: Select all

    var myIcon = {count:0, width:40, height:40, read:function(nBytes=this.data.length/2){return this.data.slice(this.count,this.count+=2*nBytes);}, data:(a=>{let[b,c]=a.split(":");c=c?.match(/.{8}/g);let d=(a,b)=>a.replace(/./g,a=>parseInt(a,10+b)-b);return b.replace(/([g-p]+)([0-9a-f]+|[q-z]+)/gi,(a,b,e)=>(/[q-z]/.test(e)?c[d(e,26)]:e).repeat(d(b,16)));})("hqhstjhshFFA084D1hFFBBA8DClqhstjjshzhFFB39DD8kqjjshzhrrhukqjjshrriukqmshsqhrxigthsuhsvhsqhshzjukqmshrxijthsvhzhrrjukqmshsuijthFFFDFCFDhrrkukqmsiltlukqmslthkrwmtlukqmsiltlukqmsiltlukqmslthkrwmtlukqmsltjrwigrhFFF1F1F3huh05F4F4F4jqmsnthrhFFF8E9B8howhFFFADF89hFFFAE296hFFF4F2EAh12F4F4F4jqmsmthrhFFF8E8B6howjvhFFFCDC77h0CF4F4F4jqmslthrwhrhnwhrqkvhFFFED550hswjqmslthrwhrhmwhrqlvhFFFFD550hsxjqmsmthrkwhhruhrvjrtkvkqmshrxlthrkwhgruhrvkrtkvkqmshsqhrxkthrhjwhrqpvkqhishrhiwhrqhgvkqhishrkwnruhrvnrtkvkqhishrkwmruhrvlrthFFECB821hFFECBB2ChFFEABA2FkvkqhishrpwhrqmvhFFF4F1E7krhFFF4F2EBhFFE8D8BAkqhishrowhrqlvirhsyhxisrhxhszirhswiqhhshzhrkwjruhrvjrthFFEDBA21hrthtqhtrhrymxhryhFFFAAF97hE8F4EFEEhqh0AF4F4F4psjthrkwiruhrvlrthtqhFFFBAB93hgxhtshrhqoshzjthrlwhrqkvhFFFDD862htthtrhgxhrshyhtuhqoshrrjthrkwhrqmvhrhrypxhrsiyhrzhrnshzhujthrhFFF8E8B4iwhrqhFFFFD759lvhrhsypxhrskyhtvhqlshzhrrhukthrhFFF8E8B3iwmvhrpxhrsmyiqjshzhrriukthulrkvhrhsrixhtwothtxiyhssjqhshzhrrjuktiujthrkvhrhsrixhtwothtxiyhsskqluktiujthrjvhtthrmxhrspylqkuktiujthrivhFFF4F1E9hthrhszkxhrspyhtynqhhuhrhvhFFF5EED7juhrhryixhrspyhrzhrhpqhrkqhrhFFFBAF97hxhrshgyhtzimqhuqhtshgyhFFFB9C7Ehrilqh0EF4F4F4hqhuqhtuhrzmyhrzhtzhrhqhsxilqh14F4F4F4hqirhtvhyisshyhtyirjq:00000000FFF4F4F4FF9E81D1FFFFFFFFFF7E57C2FFFFD54FFFFFDF7BFFFF9372FFFF7043FF9777CDFFFFDF78FF8059C2FFFF825BFFEDB920FFF1CA58FFF1CA55FFCDCDCDFFE9E3F3FFFD9372FFFE7145FF9F83D1FFFD9474FFFE7448FFBCA9DDFFFCFCFCFFE8E2F206F4F4F401F4F4F4FFF9B8A4FFF9B8A3FFF4F1F1FFFAB19AFFFC9B7CFFF4F3F2FFFAA286FFF9AF97FFFFFDFCFFFFFCFCFFF9AF98FFFAA489FFF4EFEE")};
    
    app.addMenuItem( {
        cName: "saveNoAnnots",
        cUser: "Save Without Markup",
        oIcon: myIcon,
        cParent: "File", // Adding to the file menu for the regular UI
        nPos: "cmd.saveTo", // Adding after the "Save To" option
        cRbParent: 'JS:QuickAccess', // add to the quick access bar on the ribbon
        nRbPos: "cmd.save", // put the icon after the 'save' button
        cEnable: "event.rc = (event.target != null);", // this line is optional: this disables to the tool button when there's no file active
        cExec: "saveWithoutAnnots(this, true);",
    });
  5. See my description above or the pdf documentation I made for the parameters.
  6. That's it. You save this file into the javascripts folder and you don't need to also save the png there. It will load the next time you restart PDF-XChange.
image(2).png
image(2).png (7.88 KiB) Viewed 2480 times

Plus
Actually there is another simple method to add an icon that I didn't mention above: It's not a custom icon, it's one of the built-in icons to PDF-XChange. Instead of creating the icon file, and saving it or encoding it, you use cIconID instead of oIcon thus:

Code: Select all

cIconID: 'ico.text',
[Edit]See the post below by @TheHipshaker for the complete list of icon ID strings.

The limitation on this method is that there is no documentation of the icon names, that I know of. The only icon names I'm aware of are "ico.plugin", "ico.pencil", "ico.pageWhite", "ico.delete", "ico.moreColors", "ico.preset", "ico.find", "ico.folder", "ico.text"
Last edited by Mathew on Tue Apr 01, 2025 8:40 pm, edited 15 times in total.
KD952
User
Posts: 109
Joined: Mon Feb 13, 2023 6:13 am

Re: [javascript] Two ways to add a menu icon to your script

Post by KD952 »

Hello Mathew!

Thank you for the detailed guide!
Mathew wrote: Thu Dec 12, 2024 6:55 pm Thievery: I'm no graphic artist so I usually take screen captures of the icons in PDF-XChange and modify them - hopefully they don't sue me :mrgreen:
Just send them a link to the following song:
https://youtu.be/k5ybfzRjCyw?si=KbLP-bifRbuheQGi&t=26
They will understand. :wink:

Kind regards,
Daniel
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19794
Joined: Mon Jan 12, 2009 8:07 am
Contact:

Re: [javascript] Two ways to add a menu icon to your script

Post by Stefan - PDF-XChange »

Hello Mathew,

YOU THIEF! :D :D :D
I presume it is not a problem as long as you are reusing our icons for your new tools added to our software, and are not doing it "for profit" but I will double check with senior team members to make sure that this is not in breach of some legal terms - just so that I can give you the piece of mind!

Many thanks for sharing that tutorial! I am sure it would be useful to others as well!

Kind regards,
Stefan
Mathew
User
Posts: 564
Joined: Thu Jun 19, 2014 7:30 pm

Re: [javascript] Two ways to add a menu icon to your script

Post by Mathew »

Tracker Supp-Stefan wrote: Fri Dec 13, 2024 10:36 am I will double check with senior team members to make sure that this is not in breach of some legal terms - just so that I can give you the piece of mind!
Aack Lawyers! I modified my post slightly ;) I'm absolutely only profiting in the kind comments people post.

[begin rant] I actually feel very strongly about the whole subject: It's one of the reasons I'd much rather post code here than on, say, github. I really dislike the idea of the wholesale scraping of peoples work to train AI models. These models just turn around, rearrange it slightly and spit it back out giving zero credit, while hiding any possible licensing terms or credit to the actual author -- all to profit the owner of the AI model, not the original authors. I think all creative work (including writing software) builds on the work of others, that credit should always be given where due. I notice the large number of credits in PDF-XChange's About dialog.[/rant]

Another aspect that I very much appreciate with PDF-XChange is not just allowing tinkerers like me, but often actually helping us come up with what in effect is customization of the application. This is very much in contrast to the direction many companies are going where not only can one not customize it, but the software becomes ephemeral and changes/updates happen whether one wants them or not, and the software stops working the moment the internet connection (or the company itself or their support of that product line) go down. So: thank you.
Last edited by Mathew on Tue Dec 17, 2024 4:06 pm, edited 2 times in total.
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19794
Joined: Mon Jan 12, 2009 8:07 am
Contact:

Re: [javascript] Two ways to add a menu icon to your script

Post by Stefan - PDF-XChange »

Mathew wrote: Fri Dec 13, 2024 7:35 pm Aack Lawyers! I modified my post slightly ;) I'm absolutely only profiting in the kind comments people post.
And you are quite rich in such comments Mathew! We definitely appreciate your effort greatly and are thankful for all the code you are sharing.

You have [begin rant], but I can't see the closing - so the above post needs some debugging :P

We do try to be the exception to the rules when that is of benefit to everyone involved, and we definitely do listen to what everyone has to say, and while sometimes we have to say no - when the suggestions are good, and the customizations helpful - we are also happy to allow those to happen and even assist in their implementation!

Once again thanks for your kind words and effort and
Happy holidays!

Cheers,
Stefan
Mathew
User
Posts: 564
Joined: Thu Jun 19, 2014 7:30 pm

Re: [javascript] Two ways to add a menu icon to your script

Post by Mathew »

KD952 wrote: Fri Dec 13, 2024 10:31 am They will understand. :wink:
I very much enjoyed the song :oops:
Tracker Supp-Stefan wrote: Tue Dec 17, 2024 11:20 am You have [begin rant], but I can't see the closing - so the above post needs some debugging :P
oops fixed ;)

Happy holidays to you all, and to those of you in Ukraine my heart is with you all.
TheHipshaker
User
Posts: 8
Joined: Tue Aug 17, 2021 11:59 am

Re: [javascript] Two (plus) ways to add a menu icon to your script

Post by TheHipshaker »

Hi and thanks Mathew from me as well. I've been taking advantage of your insights here a lot.
Now I can give something back, if you haven't found that yourself...

The full list of icons usable is available as the bookmarks in here:
C:\Program Files\Tracker Software\PDF Editor\Resources.dat\VectorIcons\Icons.pdf
(open Ressource.dat with your unzipper of choice)
It is a pdf file with 2044 pages. Each one of the precious icons we can use.
Not only the 'ico._' are usable but also the 'cmd._' are usable. All I found was that you need to omit the last number.
So the bookmark is called 'cmd.document.createStampFromActiveDoc.24'
In the Button it should say: "cIconID: 'cmd.document.createStampFromActiveDoc',"

I hope this doesn't offend anyone...

Best regards
250401 123115 Screenshot PDFXEdit GtQq.png
250401 123205 Screenshot pSdy.png
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19794
Joined: Mon Jan 12, 2009 8:07 am
Contact:

Re: [javascript] Two (plus) ways to add a menu icon to your script

Post by Stefan - PDF-XChange »

Hello TheHipshaker,

Thanks for sharing that info!

Kind regards,
Stefan
User avatar
⚜ Kenny Lemens, P.E. ᵂᴵ
User
Posts: 34
Joined: Thu Jan 23, 2025 4:09 pm

Re: [javascript] Two (plus) ways to add a menu icon to your script

Post by ⚜ Kenny Lemens, P.E. ᵂᴵ »

Greetings,

Thank you TheHipshaker! Well done! I will need to keep record of your post for my future reference.
On a side note: Unzipping that *dat file reminds me of excel files (XLSX), which you can also unzip.

May this be of Good Help;
⚜ Kenny Lemens, P.E. ᵂᴵ
User Plugins: https://is.gd/A9HMPG || PDF-XChange Icons: https://is.gd/Z4GeG8
[Migration] Revu Bluebeam 17 to PDF-XChange Editor: https://is.gd/8Xs1OF
Mathew
User
Posts: 564
Joined: Thu Jun 19, 2014 7:30 pm

Re: [javascript] Two (plus) ways to add a menu icon to your script

Post by Mathew »

TheHipshaker wrote: Tue Apr 01, 2025 10:33 am The full list of icons usable is available as the bookmarks in here:
C:\Program Files\Tracker Software\PDF Editor\Resources.dat\VectorIcons\Icons.pdf
(open Ressource.dat with your unzipper of choice)
Thank you @TheHipshaker! I'll update to point to your post for that information. These look like the command IDs listed in the Command Properties dialog.
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 10910
Joined: Wed Jan 03, 2018 6:52 pm

[javascript] Two (plus) ways to add a menu icon to your script

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Post Reply