Change annotation colors tool

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

Moderators: TrackerSupp-Daniel, Tracker Support, Paul - Tracker Supp, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Change annotation colors tool

Post by Mathew »

Often I need to change the color of multiple annotations. For everything except the text color, the properties toolbar works fine if you want to set the color of all outlines, or fills the same. But often I want to change all items of the same color, including text. Some things may, for example, have a red fill that I want to change, but I don't want to change the white fill on text boxes. I made the attached tool so I could also change the color of text and all other things of a specific color at the same time.

To install, unzip and put the file "change colors.js" into the Javascripts folder (either in the application folder, or at C:\Users\[YOUR USER NAME]\AppData\Roaming\Tracker Software\PDFXEditor\3.0\Javascripts)
change colors v1.4.1.zip
Extract the zip and save in the Javascripts folder either in the application folder, or in C:\Users\[USERNAME]\AppData\Roaming\Tracker Software\PDFXEditor\3.0\Javascripts
(9.3 KiB) Downloaded 2 times
It will add a toolbar button to the add-in toolbar:
image.png
image.png (1.25 KiB) Viewed 1089 times
and a "Change Colors" menu item under the "Tools" menu (for the classic toolbars). If you select multiple annotations and run it, it will list all the colors in the selected annotations and give you options to change those colors.
image(1).png
There are some typical colors in the dropdown menu, or you can add your own values. Only those colors that you change are affected.

You can view/edit the colors either in hexadecimal format, or in Adobe's decimal format.

To change the saved name of any custom color, press the "Edit custom color names…" button at the lower left. It will open a dialog that you can edit the color names. Warning: It will allow you to override the standard color names with a different color - but that can get quite confusing.
image(2).png
image(2).png (40.52 KiB) Viewed 128 times
Last edited by Mathew on Tue Apr 23, 2024 6:03 pm, edited 11 times in total.
User avatar
Ovg
User
Posts: 461
Joined: Tue Sep 05, 2017 4:56 pm

Re: Change annotation colors tool

Post by Ovg »

Hello Mathew!

First of all Thank you for sharing your useful tools!

But it seems that you didn't attach file to your post in this topic ...
It's impossible to lead us astray for we don't care even to choose the way.
PDF-XChange PRO, 10.1.1 (Build 381) / W7 SP1 x64
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello Ovg, Mathew,

Please note that the forums won't accept .js attachments and they have to be zipped first (You did mention to unzip in your instructions - but maybe you dragged the non zip version of the file and it was just removed by the forum?).
Looking forward to trying out the tool myself!

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

Re: Change annotation colors tool

Post by Mathew »

OOoops! I've added above - and here.
change colors v1.0.zip
place into Javascripts folder
(6.4 KiB) Downloaded 43 times
User avatar
Paul - Tracker Supp
Site Admin
Posts: 6903
Joined: Wed Mar 25, 2009 10:37 pm
Location: Chemainus, Canada
Contact:

Re: Change annotation colors tool

Post by Paul - Tracker Supp »

Hi, Mathew

Very cool.

Kind regards,
Paul - Tracker Supp
Best regards

Paul O'Rorke
Tracker Support North America
http://www.tracker-software.com
User avatar
Ovg
User
Posts: 461
Joined: Tue Sep 05, 2017 4:56 pm

Re: Change annotation colors tool

Post by Ovg »

Hello Mathew!

:thumbsup::fire:
It's impossible to lead us astray for we don't care even to choose the way.
PDF-XChange PRO, 10.1.1 (Build 381) / W7 SP1 x64
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Change annotation colors tool

Post by Tracker Supp-Stefan »

:)
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

A few very minor changes:
  • saves up to 8 custom colors you enter so they are in the colors popup menu item (edit MAX_SAVED_COLORS to change this value)
  • changed the icon slightly to make it look less like the customize toolbars icon ;)
change colors v1.1.zip
unzip and put the file "change colors.js" into the Javascripts folder
(6.49 KiB) Downloaded 50 times
User avatar
TrackerSupp-Daniel
Site Admin
Posts: 8624
Joined: Wed Jan 03, 2018 6:52 pm

Change annotation colors tool

Post by TrackerSupp-Daniel »

:)
Dan McIntyre - Support Technician
Tracker Software Products (Canada) LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

I realized that most annotation types can have rich text content, so this updates it to be able to change colors in dimension line text, for example.
change colors v1.2.zip
unzip and put into the javascripts folder
(6.48 KiB) Downloaded 66 times
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello Mathew,

Many thanks for the update to this script as well!

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

Re: Change annotation colors tool

Post by Mathew »

Very minor change to deal with bug in dialog box width.
change colors v1.2.1.zip
Unzip and put in Javascripts folder
(6.7 KiB) Downloaded 19 times
User avatar
PHK
User
Posts: 960
Joined: Tue Nov 24, 2020 4:02 pm

Re: Change annotation colors tool

Post by PHK »

For me, this is a much-needed tool. Thank you, Mathew.
All best,

FringePhil
User avatar
TrackerSupp-Daniel
Site Admin
Posts: 8624
Joined: Wed Jan 03, 2018 6:52 pm

Change annotation colors tool

Post by TrackerSupp-Daniel »

:)
Dan McIntyre - Support Technician
Tracker Software Products (Canada) LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

This is really great. Thank you, Matthew.
This should really be part of PDF-XCE...
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Change annotation colors tool

Post by Tracker Supp-Stefan »

:)
Toygun
User
Posts: 52
Joined: Fri Sep 06, 2019 9:08 am

Re: Change annotation colors tool

Post by Toygun »

Thanks Mathew. The tool works smoothly.
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Tracker Supp-Stefan wrote: Fri Mar 08, 2024 11:44 am :)
So will you? With Matthew's permission? Add a menu like this?

Maybe with a # 6 digit Hex color code option as well?
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster,

Just spoke with a colleague from the dev team - and for now we have no plans to make this a built in feature of the Edtor.
That way we would both give Credit to Mathew as it's due, and also as he has shared the code here in the forums - this makes that script effectively open source - and would allow anyone who needs a slightly modified version for their particular needs to create that themselves.

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

Re: Change annotation colors tool

Post by Mathew »

I absolutely consider this open source - change/use as you see fit. All these tools are things that I've run into a need for, so if they were built-in that would be fantastic too. They work fine as part of the add-in toolbar, and if at some point Tracker makes it possible to put add-in tool buttons in to appropriate places in the ribbon, it could be pretty seamless. Javascript does have some limitations: a built-in version of this tool, for example, would be much better because you could use the color picker instead of my rather clumsy workaround.

But if one were to do a built-in version, I think a better approach would be a sort of multi-select/change tool that allows you to:
1. filter which annotations are selected by their properties, and then
2. change any of the properties of the selection (not just color, but any of the properties such as author/date/linetype/thickness/fill color/text color/rotation/etc)
Most of this is doable with javascript, so I may do it at some point if I find time.
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

I can't seem to find the javascript folder.

ps. this is what windows defender says about the v1.2.1. script
image.png
image(1).png
image(2).png

what wasthe alternative location you were tallkingg aboutt
image(3).png
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
TrackerSupp-Daniel
Site Admin
Posts: 8624
Joined: Wed Jan 03, 2018 6:52 pm

Re: Change annotation colors tool

Post by TrackerSupp-Daniel »

Hello, MedBooster

The JavaScripts folders don't exist by default, you would create it in one of these two locations:

%appdata%\Tracker Software\PDFXEditor\3.0
or the install directory (by default):
C:\Program Files\Tracker Software\PDF Editor

Kind regards,
Dan McIntyre - Support Technician
Tracker Software Products (Canada) LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

TrackerSupp-Daniel wrote: Mon Mar 11, 2024 8:38 pm %appdata%\Tracker Software\PDFXEditor\3.0
or the install directory (by default):
C:\Program Files\Tracker Software\PDF Editor
and the folder name must be "Javascripts" exactly:
image.png
or in AppData (which is where I put the scripts):
image(1).png
It doesn't seem to care about capitalization, but I got stymied for a while because I initially named it (wrong) "javascript" which is the term that app.getPath() uses.
User avatar
TrackerSupp-Daniel
Site Admin
Posts: 8624
Joined: Wed Jan 03, 2018 6:52 pm

Change annotation colors tool

Post by TrackerSupp-Daniel »

:)
Dan McIntyre - Support Technician
Tracker Software Products (Canada) LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Wooow Mathew that's a lot of scripts, any others you have shared on the forum? If so maybe you could just create a single thread with all scripts you're willing to share? :))
viewtopic.php?p=175299#p175299
I remember you made this script to rename bookmarks as well ↑

PS:
I assumed that I could add the folder myself, but I still don't see anything after having added a Javascripts folder hmm..
image.png
Or maybe it's just that I don't see where the Javascript function buttons are supposed to appear

edit: maybe the folder name must be "JavaScript", not Javascript, IDK if capital letters matter.
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Mathew wrote: Sun Jun 18, 2023 11:52 pm It will add a toolbar button and a "Change Colors" menu item under the "Tools" menu. If you select multiple annotations and run it, it will list all the colors in the selected annotations and give you options to change those colors.

Where is this "Tools" menu... ? I don't see it
image.png
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Jordan - Tracker Supp
Site Admin
Posts: 91
Joined: Mon Jul 03, 2023 3:10 pm

Re: Change annotation colors tool

Post by Jordan - Tracker Supp »

Hello MedBooster,

As all other Java Scripts Mathew's tool is placed in the "Add-on Tools" ribbon tab:
image.png
I hope this helps.
Best regards,
Jordan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Oh and like Mathew said, it would be great if you were able to place these Javascript buttons freely, and maybe be able to activate it with a *keyboard shortcut* as well.
image.png
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Oh and I've looked into the script and I've tried to add a HeX field, but it's difficult... so if anyone has the time, I'm sure the rest of us wouldn't mind.

It's a really smart script though, it took a while before I realized that all current colors get their own field.
It would have been nice if there were a field to change the color of ALL selected annotations, regardless what the current color is:
image.png
It would also be super cool if you were actually able to see the color generated in the menu.... next to the RGB color codes... However, Javascript might not be able to do this... I reckon
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster,

As per the other topic - I believe we have a feature request for that - to be able to adjust the common properties of annotations even if annotations of different types are selected. I can't tell you when that might be available though.

As for the script and the HEX values - if you have colours in that format - there are online tools that can easily convert them for you to the decimal ones you need for this script.

Kind regards,
Stefan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Btw. what determines the order of the colors? It's unfortunate that there is no square with the color being referred to / the color produced.




I have some AutoHotKey experience, but JavaScript is very difficult, I don't see anything referring to item_id: "cCxx", .... So it's difficult to make the content of this match a new HeX field.
image(2).png

Code: Select all



// script to add a change colors tool
// tool data and custom icon
var iconSet_colorsTool = { button:
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF42A5F5FF42A5F5FF42A5F5FF42A5F5FF42A5F500000000FFFF7043FFFF7043FFFF7043FFFF7043FFFF704300000000FFD70C50FFD70C50FFD70C50FFD70C50FFD70C50000000000000000000000000FF84C0F6FF47A7F5FF42A5F5FF42A5F5FF42A5F500000000FFFF794FFFFF7043FFFF7043FFFF7043FFFF704300000000FFF73C68FFD70C50FFD70C50FFD70C50FFD70C50000000000000000000000000FF89C4F6FF66B6F6FF47A7F5FF3FA4F5FF42A5F500000000FFFF8F6DFFFF7A51FFFF7043FFFF7043FFFF704300000000FFFF597DFFF73C68FFD70C50FFD70C50FFD70C50000000000000000000000000FF8AC4F7FF71BBF7FF65B5F6FF44A6F5FF42A5F500000000FFFF9271FFFF906EFFFF7A51FFFF7043FFFF704300000000FFFF597DFFFF597DFFF73C68FFD70C50FFD70C50000000000000000000000000FF8CC5F6FF71BBF7FF71BBF7FF65B5F7FF42A5F500000000FFFF9271FFFF9372FFFF906EFFFF7A51FFFF704300000000FFFF597DFFFF597DFFFF597DFFF73C68FFD70C500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF7D55C2FF7D55C2FF7D55C2FF7D55C2FF7D55C200000000FFFFA726FFFFA726FFFFA726FFFFA726FFFFA72600000000FF000000FF000000FF9D9D9DFFD6D6D6FF9D9D9D000000000000000000000000FF8E6DC9FF7D55C2FF7D55C2FF7D55C2FF7D55C200000000FFFFB74DFFFFA92CFFFFA726FFFFA726FFFFA72600000000FF323232FF9D9D9DFFD6D6D6FFFBA98FFFFD815A80FD89640000000000000000FF9D80D1FF8E6DC9FF7D55C2FF7D55C2FF7D55C200000000FFFFBD5BFFFFB850FFFFA92CFFFFA726FFFFA72600000000FFA1A1A1FFD7D7D7FFFAE098FFFDAA83FFFF7043FFFD896480FD896400000000FFAD96D7FF9D80D1FF8E6DC9FF7D55C2FF7D55C200000000FFFFBC59FFFFBD5CFFFFB850FFFFA726FFFFA7265FF4F4F4FFD7D7D7FFFAD28EFFFCDE80FFFDDF84FFFC9D6FFFFF7043FFFD815A00000000FFAD96D7FFAD96D7FF9D80D1FF8E6DC9FF7D55C200000000FFFFBC59FFFFBC59FFFFBD5CFFFFB850FFFBC8A0BEF4F4F4FFFBC679FFFFBD5CFFFCCC79FFFDDB6BFFFDD55CFFFC8F5AFFFB9575000000000000000000000000000000000000000000000000000000000000000000000000000000005FF4F4F4BEF4F4F4FFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFCBB4DFFFDD557FFFADA83BEF4F4F400000000FF85B850FF79B23CFF7BB23FFF79B23CFF79B23C00000000FFFDDF87FFFDDF87FFFAE7BAFFF6EFDFFFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFAC975BEF4F4F45FF4F4F400000000FF9CC671FF85B850FF79B23CFF7BB23FFF79B23C00000000FFFEE392FFFAE7BAFFF6EFDFFFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFCBA5BFFF7F7F75FF4F4F40000000000000000FFABCD8AFF9CC671FF85B850FF79B23CFF79B23C00000000FFFEE28DFFF7F0E0FFF9CB8AFFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFCBA5BFFF7F7F7FFFBFBFB000000000000000000000000FFBBD5A2FFABCE8AFF9CC671FF85B850FF79B23C00000000FFFDE291FFF5EDE7FFF9DBC1FFFCC372FFFFB241FFFFA726FFFFA726FFFCBA5BEEF6F6F6FFFBFBFBFFFFFFFF000000000000000000000000FFBBD5A2FFBBD5A2FFABCE8AFF9CC671FF85B85000000000FFFDE291FFF6E4D4FFFAD9BCFFF8D6B6FFFCB044FFFFA726FFFCBA5BEEF6F6F6D6FAFAFABEFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000FFCCC5BFFFF5D1AFFFF9CDA6FFF7D0ACFFFAC273BEF4F4F45FF4F4F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF000000FFC1B8B0FFF6DFCBFFF4ECE5BEF4F4F45FF4F4F4000000000000000000000000000000000000000000000000",
iconStream:function(val){var data=this[val];
	return {count:0, width:20, height:20, read:function(nBytes){return data.slice(this.count,this.count+=2*nBytes)}}}
};
// This adds a button to the Add-on Tools toolbar
app.addToolButton( {
	cName: "changeColorAllTool",
	cLabel: "Colors…",
	oIcon: iconSet_colorsTool.iconStream("button"),
	cTooltext: "Change Colors of Selected Annotations…",
	cEnable: "event.rc = (this.selectedAnnots && this.selectedAnnots.length)",
	cExec: "changeColorsAll(this)" }
);
// This adds a menu item
app.addMenuItem( {
	cName: "changeColorAllMenu",
	cUser: "Change Colors…",
	oIcon: iconSet_colorsTool.iconStream("button"),
	cParent: "Tools", // Change this to "Comments" to put in the Comment menu, etc
	//nPos: 13,
	cEnable: "event.rc = (this.selectedAnnots && this.selectedAnnots.length)",
	cExec: "changeColorsAll(this)" }
);


//Added HeX extra MB











































//End of HeX code






/* Script to change color of all annotations with a dialog
		v 1.2		date Sep 20, 2023
	only tested on PDF-Xchange Editor v10.0
 * History:
   v1.0	Jun 20, 2023 Initial release
   v1.1	Jul 04, 2023 Fix to global variable access, revise icon
   v1.2 Sep 20, 2023 Look at rich contents in all annotations
*/

function changeColorsAll (t) {
	const MAX_SAVED_COLORS = 8; // This is the number of custom colors that will be saved
	
	//  ************************* Begin Color Utility ********************************
	const cUtil = {
		defaultColors: { 
			"Black":color.black,
			"Dark Gray 25%":color.dkGray,
			"Gray 40%":["G",0.4],
			"Gray":color.gray,
			"Light Gray 75%":color.ltGray,
			"White":color.white,
			"Transparent":color.transparent, // only in here because selected items will have it
			"Dark Red":["RGB",139/255,0,0],
			"Red":color.red,
			"Rose":["RGB",1,228/255,225/255],
			"Light Orange":["RGB",1,173/255,91/255],
			"Orange":["RGB",1,104/255,32/255],
			"Gold":["RGB",1,215/255,0],
			"Yellow":color.yellow,
			"Light Yellow":["RGB",1,1,224/255],
			"Lime":["RGB",50/255,205/255,50/255],
			"Pale Green":["RGB",152/255,251/255,152/255],
			"Bright Green":color.green,
			"Sea Green":["RGB",60/255,179/255,113/255],
			"Green":["RGB",0,147/255,0],
			"Dark Green":["RGB",0,85/255,0],
			"Aqua":["RGB",127/255,1,212/255],
			"Teal":["RGB",56/255,142/255,142/255],
			"Turquoise":["RGB",64/255,224/255,208/255],
			"Sky Blue":["RGB",192/255,1,1],
			"Light Blue":["RGB",125/255,158/255,192/255],
			"Cyan":color.cyan,
			"Blue":color.blue,
			"Dark Blue":["RGB",0,0,139/255],
			"Indigo":["RGB",75/255,0,130/255],
			"Midnight Blue":["RGB",0,0,94/255],
			"Plum":["RGB",72/255,0,72/255],
			"Pink":["RGB",1,192/255,203/255],
			"Violet":["RGB",128/255,0,128/255],
			"Magenta":color.magenta,
			"Blue-Grey":["RGB",123/255,123/255,192/255],
			"Brown":["RGB",165/255,142/255,0],
			"Tan":["RGB",210/255,180/255,140/255],
			
			//custom colors added by MB
			"CBlue":["RGB",69/255,163/255,255/255],
			"CPink":["RGB",255/255,192/255,203/255],
			"CViolet":["RGB",200/255,126/255,231/255],
			"CGreen":["RGB",135/255,206/255,111/255],
			"COrange":["RGB",245/255,188/255,82/255],
			"CBrown":["RGB",210/255,180/255,140/255],
			"CYellow":["RGB",255/255,238/255,88/255],
			
		},
		otherColorText: "Other - Enter:",
		savedCls: {},
		annotCls: {},
		// inititalize saved and annotation colors
		initialize: function(savedColors, annots) {			
			// add the saved colors (clobbers what's in there)
			this.savedCls = savedColors || {};
			// add the annotation colors
			this.annotCls = this.getColors( annots, [] );
		},
		// returns object {colorName:color,...}
		getSavedColors: function( withOtherClr=false, withAnnotCls=false ) {
			let sc = {};
			let gsc = [ this.defaultColors, this.savedCls ];
			// get other colors text
			if (withOtherClr)
				sc[ this.otherColorText ] = "";
			// build color associative array
			// because the key is the color name, if a duplicate color has been saved with a different name, it will show up
			gsc.forEach( cl => Object.assign(sc, cl) );
			// add in annotation colors
			// this checks that it's not already in the list
			if (withAnnotCls) {
				let selClrs = this.findColors( Object.values( this.annotCls ), Object.values( sc ) ); // array
				// doesn't bother to keep the text of the color
				Object.assign(sc, this.colObj(selClrs));
			}
			return sc;
		},
		
		

		
		
	
		// get list of stroke colors of annotations, and only return those that are not in colorList[]
		// returns object {colorName:color,...}
		getColors: function(annots, colorList){
			let fL = [];
			for (let i in annots) {
				let ann = annots[i];
				
				// get colors from richContents
				if ( ann.richContents && ann.richContents.length )
					fL = fL.concat( ann.richContents.map( rc => rc.textColor ));
				//	default:
				if ( ann.strokeColor ) fL.push( ann.strokeColor );
				if ( ann.fillColor ) fL.push( ann.fillColor );

			};
			
			fL = this.findColors(fL, colorList);

			return this.colObj(fL);
		},
		// returns only the colors in findList[] that are not in colorList[]
		// returns array of colors
		findColors: function(findList, colorList) {
			let addList =[];
			for ( let fc of findList ) {
				let ceq = colorList.some( c => cUtil.equal( fc, c ) );
				if (!ceq) { // not in the list, so add it
					addList.push( fc );
				};
			};
			return addList;
		},
		// add a color to the saved colors list
		// returns object {colorName:color,...}
		addlClrs: function( addColor, currColors=this.savedCls ) {
			// will not add if it's in the default colors list
			let ac = this.findColors( [addColor], Object.values(this.defaultColors));
			// need to see if it's already in the list
			if (ac.length) {
				ac = this.findColors(ac, Object.values(currColors));
			}
			// ac is null if no additional colors
			if (ac.length) {
				this.trimObj( currColors, MAX_SAVED_COLORS-1 );
				// add ac to the currColors list and return
				Object.assign( currColors, this.colObj(ac) );
			}
			return currColors;
		},
		// make a color:value list of colors
		// returns object {colorName:color,...}
		colObj: function(colList) {
			let colOb = {};
			// use the default colors to find actual color names
			let cNames = Object.keys( this.defaultColors );

			for ( let c of colList ) {
				let cN = cNames.find( cc => cUtil.equal( this.defaultColors[cc], c ));
				if ( undefined == cN ) cN = this.colArr256(c);
				colOb[ cN ] = c;
			};

			return colOb;
		},
		// change the values to 256 based and return string
		colArr256: function(colr) {
			let c = [colr[0].toUpperCase()];
			for (let i=1; i<colr.length; i++){
				c[i] = Math.round( 255*colr[i] );
			}
			return c.join(", ");
		},
		// change 256 based string to color array
		colFromStr: function(colStr) {
			let sColor = colStr.split(",");
			sColor[0] = sColor[0].toUpperCase();
			// maybe should check if it's in the correct format?
			for (let i=1; i<sColor.length; i++ ) {
				sColor[i] = sColor[i] / 255;
			}
			return sColor;
		},
		trimObj: function (ob,maxL) {
			// deletes from the front of ob.
			let ol = Object.keys(ob).length - maxL;
			for (let i in ob) {
				// trim length
				if ( ol > 0 ) {
					delete ob[i];
					ol--;
				} else {
					break;
				}
			}
			//return ob;
		},
		// based on the color.equal, but added rounding
		equal : function (c1, c2) {
			if (c1[0] == "G") {
				c1 = color.convert(c1, c2[0]);
			}
			else {
				c2 = color.convert(c2, c1[0]);
			}
			if (c1[0] != c2[0]) {
				return false;
			}
			let nComponents = 0;
			switch (c1[0]) {
				case "G":
					nComponents = 1;
					break;
				case "RGB":
					nComponents = 3;
					break;
				case "CMYK":
					nComponents = 4;
					break;
				case "HeX": //MB added
					nComponents = 3;
					break;					
				default: ;
			}
			for (let i = 1; i <= nComponents; i++) {
				if ( Math.round(c1[i]*255) !=  Math.round(c2[i]*255) ) {
					return false;
				}
			}
			return true;
		}
	}
	
	//  ************************* Begin Object Utility ********************************
	const obUtil = {
		// get object with prop == val
		getObj: function ( obj, prop, val ) {
			let found;
			if  ( obj[prop] == val ) {
				return obj;
			} else {
				if (obj.elements) {
					for (let e in obj.elements) {
						found = this.getObj( obj.elements[e], prop, val );
						if (found) break;
					}
				}
			};
			return found;
		},
	}
	
	//  ************************* Begin Dialog ******************************** 
	const colorDialog = {
		colors:[],
		colorKeys:[], 	// to hold all the colors for the dropdowns (keys - text)
		data:[],		// dialog results
		selColors:[],	// selected color (index on colors or colorKeys)
		nClrs: () => colorDialog.selColors.length ,		// number of selected colors
		//nAnns: 0,
		
		initialize: function (dialog) {
			let dLoad = {}; //cUtil.updateObject( {}, this.data ); // don't change data
			// need to deal with the popups
			for (let i=0;i<this.nClrs();i++) {
				let butn = util.printf("%02d", i);
				dLoad[ "cE"+butn ] = this.colorKeys[ this.selColors[i] ];
				dLoad[ "cC"+butn ] = cUtil.colArr256( this.colors[ this.selColors[i] ] );
				dLoad[ "cP"+butn ] = this.getListboxArray( this.colorKeys, this.selColors[i] );
			};
			dialog.load( dLoad );
		},
		commit:function (dialog) { // called when OK pressed
			this.data = dialog.store();
			// need to deal with the popups
			for (let i=0;i<this.nClrs();i++) {
				let butn = util.printf("%02d", i);
				this.data[ "cP"+butn ] = this.getIndex( this.data[ "cP"+butn ] );
			};
			// return "ok"
		},
		// returns the index number of the first item with positive number value
		getIndex: function (elements) {
			for (let i in elements) {
				if ( elements[i] > 0 ) {
					return elements[i]-1; //i ; the index is the text of the dropdown
				}
			}
		},
		
		// create object array suitable for the listbox. selItem is index
		// returned array is {"Displayed option":-order,...}
		getListboxArray: function(vals, selItem) {
			let sub = {};
			for (let i=0; i<vals.length; i++) {
				// positive number if selected
				sub[vals[i]] = ((selItem == i)?1:-1)*(i+1);
			}
			return sub;
		},
		// change to the custom color input box -- needs to be called from each box
		// butn is formatted util.printf("String format: %02d", n)
		clrInput: function (dialog,butn) { 
			let results = dialog.store();
			let pickedIndx = this.colors.findIndex( c => cUtil.equal( c, cUtil.colFromStr( results["cC"+butn] ) ));
			if ( pickedIndx < 0 ) pickedIndx = 0;
			let dLoad={};
			dLoad["cP"+butn] = this.getListboxArray( this.colorKeys, pickedIndx );
			dialog.load( dLoad );	
		},
		clrDropdn: function (dialog,butn) { // change to the dropdown
			let results = dialog.store();
			// update the custom color box
			let pickedClr = this.colors[ this.getIndex( results["cP"+butn] ) ];
			if ( pickedClr ) { // should be falsy "" for othercolor
				let dLoad={};
				dLoad["cC"+butn] = cUtil.colArr256(pickedClr);
				dialog.load( dLoad );
			}
			//dialog.enable({"cClr": (results["hClr"][cUtil.otherColorText] > 0)});
		},
		description: {
			name: "Replace Color", // Dialog box title
			align_children: "align_left",
			width: 380,
			//height: 200,
			elements:
			[{	type: "cluster",
				name: "Colors", 
				align_children: "align_left",
				item_id: "Ctnr", // this name is used to get the container for the dropdowns
				elements:
				[{	type: "view",
					align_children: "align_row",
					name:"Headings",
					//item_id: "Ctnr", 
					elements:
					[
					{	type: "static_text",
						name: "Current Color RGB",
						width: 100,
						alignment: "align_center",
						bold: true
					},
					{	type: "static_text",
						name: "Current Color HeX",
						width: 100,
						alignment: "align_center",
						bold: true
					},					
					{	type: "static_text",
						name: "|",
						width: 5
					},
					{	type: "static_text",
						name: "Select New Color",
						width: 100,
						bold: true
					},
					{	type: "gap",
						width: 20 // for the dropdown arrow
					},
					{	type: "static_text",
						name: "Enter Color RGB",
						alignment: "align_fill",
						//width: 120
						bold:true
					},
					//MB added first row
					{ 
                        type: "static_text",
                        name: "Enter Color Hex",
                        width: 120,
                        alignment: "align_center",
                        bold: true
                    },
					
					
					
					]
				}
				]
			},
			{	type:"static_text",
				name: "The first element in the comma separated list is a string denoting the color space \ntype. The subsequent elements are numbers that range between zero and 255 inclusive. \nFor example, the color red can be represented as [RGB, 255, 0, 0]. \nColor Space options are: \nG (Gray - single value 0 is black), RGB (3 values), CMYK (4 values).",
				font: "palette",
				alignment: "align_fill",
				width: 380,
				height:70,
			},
			{	alignment: "align_right",
				type: "ok_cancel",
				ok_name: "Ok",
				cancel_name: "Cancel"
			}
			]
		}
	};
	// menu items
	class MenuItem {
		baseMenu = {	type:"view",
			align_children:"align_row",
			//item_id: "cTxx", // typical container //MB 2nd row and down current RGB color
			elements:
			[{	type:"static_text",
				name: "Existing Color RGB", // for the existing color RGB : original "Existing Color"
				width:100,
				alignment: "align_center",
				item_id: "cExx"
			},
			//MB added new HeX current color 
			{	type:"static_text",
				name: "Existing Color HeX", // for the existing color HeX
				width:100,
				alignment: "align_center",
				item_id: "cHxx"
			},			
			
			
			
			{	type: "static_text",
				name: "|",
				width: 5
			},
			{	type: "popup",
				alignment: "align_fill",
				width: 100,
				item_id: "cPxx"
			},
			{	type: "edit_text",
				width:125,
				alignment: "align_fill",
				item_id: "cCxx",
			},
			
			//MB added HeX field 2nd row and others
			{	type: "edit_text",
				width: 60,
				alignment: "align_fill",
				item_id: "cHxx",
			}			
			
			
			]
		};
		xx;
		constructor ( num, dia ) {
			let xx = this.xx = util.printf("%02d", num);
			// relabel
			this.baseMenu.elements.forEach( e => 
				e.item_id = (e.item_id ? e.item_id.substring(0,2)+xx : null ));
		};
		// fns = { diaID:func,... }
		setHandlers ( dia, fns ) {
			let xx = this.xx;
			for ( let f in fns ) {
				dia[f+xx] = function(dialog) { dia[fns[f]]( dialog, xx ) };
			};
		};
		get() {
			return this.baseMenu;
		}
		
	};
	





















// Logic:
  // Get colors of all selected annotations
  // Build menu > curr color > new color
  // Check if any of the colors are changed & dialog "OK"
  // Make a list of old color > new color
  // For each annotation
  //    go through old color > new color list
  //	change all colors of that annotation with one .setProps()

	// get all annotation objects - try to use selected annotations
	let annArr = t.selectedAnnots;
	
	if (!annArr || !annArr.length){
		if ( t.getAnnots() ) { // ie there are some annotations in the document
			var noAnSel = app.alert({
				cMsg: "No Annotations selected, change all annotations in the current document?",
				cTitle: "Changing ALL Annotations",
				nIcon: 1, nType: 1 });
		}
		if ( noAnSel == 1 ) {
			annArr = t.getAnnots();
		} else {
			return "Nothing Selected";
		}
	}
	// try to get global variables
	let savedPrefs = CHANGE_COLORS_PREFS.get();
	if (!savedPrefs) {
		// defaults
		savedPrefs = {
			savedColors:{}
			//dialog:{},
		};
	};
	// saved values to the dialog
	//for (let d in savedPrefs.dialog)
	//	colorDialog.data[d] = savedPrefs.dialog[d]; // shallow copy

	// get the annotation colors
	cUtil.initialize( savedPrefs.savedColors, annArr );

	// initialize dialog
	//colorDialog.nAnns = annArr.length;
	let allColors = cUtil.getSavedColors( true, true );
	colorDialog.colors = Object.values( allColors );
	colorDialog.colorKeys = Object.keys( allColors );
	
	// build dialog dropdowns
	let drContainer = obUtil.getObj ( colorDialog.description, "item_id", "Ctnr" );
	drContainer.name = annArr.length + " Annotations Selected";

	// array of the annotation color values
	let annotColors = Object.values( cUtil.annotCls );
		
	for (let x in annotColors) {
		// get the annotation colors index to the colors list
		colorDialog.selColors[x] = colorDialog.colors.findIndex( c => cUtil.equal( c, annotColors[x] ));
		
		let dia = new MenuItem( x, colorDialog );
		dia.setHandlers( colorDialog, { "cP":"clrDropdn", "cC":"clrInput" } );
		drContainer.elements.push( dia.get() );
	};

//MB array for rgb to HeX

function rgbToHex(rgbArray) {
    // Ensure the input is in the correct format
    if (rgbArray.length !== 3) {
        throw new Error("RGB array must contain three values");
    }

    // Convert each RGB value to HEX
    return "#" + rgbArray.map(value => {
        const hexValue = Math.round(value * 255).toString(16);
        return hexValue.length === 1 ? "0" + hexValue : hexValue;
    }).join("");
}








	//  *** run the dialog ***
	let result = app.execDialog(colorDialog);
	
	if ("cancel" == result) return result;

	// make list of changed colors RGB
	let chCols = [];
	for (let x in annotColors) {
		// compare the new to existing colors
		let xx = util.printf("%02d", x);
		let newClr = cUtil.colFromStr( colorDialog.data["cC"+xx] );
		if ( !cUtil.equal( annotColors[x], newClr )) {
			chCols.push( {"oldCl":annotColors[x],"newCl":newClr} );
		};
	};
	
	if ( !chCols.length ) return "No colors changed";
	
	annArr.forEach( ann => {
		let revs = {};
		// get colors from richContents
		if ( ann.richContents && ann.richContents.length ) {
			let changed = false;
			let spans = [];
			for (let s in ann.richContents) {
				spans[s] = ann.richContents[s];
				for (let c of chCols) {
					if ( cUtil.equal( spans[s].textColor, c.oldCl )) {
						changed = true;
						spans[s].textColor = c.newCl;
					}
				};
			};
			if (changed) revs["richContents"] = spans;
		}
		// get colors from array items props
		let props = [ "strokeColor", "fillColor" ];
		for (let prop of props) {
			for (let c of chCols) {
				// property may not exist for this annotation
				if ( ann[prop] && cUtil.equal( ann[prop], c.oldCl ))
					revs[ prop ] = c.newCl;
			};
		};
		// apply the revisions
		if (Object.keys(revs).length) ann.setProps( revs );
	});


//MB make list of changed colors HeX






	// save the custom colors
	for ( let sc of chCols ) {
		// only add if the strokeColor isn't part of the default and saved colors
		Object.assign( savedPrefs, {"savedColors": cUtil.addlClrs( sc.newCl, savedPrefs.savedColors)} );
	};
	// update global variable
	CHANGE_COLORS_PREFS.set( savedPrefs );

	return result;
}

// need trusted function to store preferences
const CHANGE_COLORS_PREFS = new class {
	constructor(name) {
		this.get = app.trustedFunction(() => {
			app.beginPriv();
			if ( global[name] )
				return JSON.parse( global[name] );
			});
		this.set = app.trustedFunction( value => {
			app.beginPriv();
			global[name] = JSON.stringify( value );
			global.setPersistent( name, true);
			});
	}
}("CHANGE_COLORS_PREFS");

Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster,

Those are RGB - Red Green Blue values, and almost any computer colour notation will have the colours in this order - I believe due to the way subpixels are normally ordered on screens as well.

So the first 0-255 value is the Red, the next one is the Green and the last one is the blue component of your colour.
FF77AA colour will have max red, medium green and almost max blue as well - giving a pinkish colour:
image.png
And it seems like google directly gives you all conversion values of the same colour (I searched for "FF77AA colour" - and it shows me below 255, 119, 170 RGB value for the same.

Kind regards,
Stefan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

There are plenty of JavaScript scripts that turn RGB into HeX, I'm just struggling with adding it to Mathew's script

Code: Select all

//reference: https://stackoverflow.com/questions/13070054/convert-rgb-strings-to-hex-in-javascript
function componentFromStr(numStr, percent) {
    var num = Math.max(0, parseInt(numStr, 10));
    return percent ?
        Math.floor(255 * Math.min(100, num) / 100) : Math.min(255, num);
}

function rgbToHex(rgb) {
    var rgbRegex = /^rgb\(\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*\)$/;
    var result, r, g, b, hex = "";
    if ( (result = rgbRegex.exec(rgb)) ) {
        r = componentFromStr(result[1], result[2]);
        g = componentFromStr(result[3], result[4]);
        b = componentFromStr(result[5], result[6]);

        hex = "0x" + (0x1000000 + (r << 16) + (g << 8) + b).toString(16).slice(1);
    }
    return hex;
}
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

There are a few places in the script to update for changing to/from hex values, but I'll try to add it as an option.
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

@MedBooster try this. I didn't go through and test it exhaustively, but it seems to work. When I get time, I'll update the script above with a checkbox to decide if you want hex or decimal, but for now, on line 39 change "USE_HEX = true" to "USE_HEX = false" if you want to work in decimal:

Code: Select all

// script to add a change colors tool
// tool data and custom icon
var iconSet_colorsTool = { button:
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF42A5F5FF42A5F5FF42A5F5FF42A5F5FF42A5F500000000FFFF7043FFFF7043FFFF7043FFFF7043FFFF704300000000FFD70C50FFD70C50FFD70C50FFD70C50FFD70C50000000000000000000000000FF84C0F6FF47A7F5FF42A5F5FF42A5F5FF42A5F500000000FFFF794FFFFF7043FFFF7043FFFF7043FFFF704300000000FFF73C68FFD70C50FFD70C50FFD70C50FFD70C50000000000000000000000000FF89C4F6FF66B6F6FF47A7F5FF3FA4F5FF42A5F500000000FFFF8F6DFFFF7A51FFFF7043FFFF7043FFFF704300000000FFFF597DFFF73C68FFD70C50FFD70C50FFD70C50000000000000000000000000FF8AC4F7FF71BBF7FF65B5F6FF44A6F5FF42A5F500000000FFFF9271FFFF906EFFFF7A51FFFF7043FFFF704300000000FFFF597DFFFF597DFFF73C68FFD70C50FFD70C50000000000000000000000000FF8CC5F6FF71BBF7FF71BBF7FF65B5F7FF42A5F500000000FFFF9271FFFF9372FFFF906EFFFF7A51FFFF704300000000FFFF597DFFFF597DFFFF597DFFF73C68FFD70C500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF7D55C2FF7D55C2FF7D55C2FF7D55C2FF7D55C200000000FFFFA726FFFFA726FFFFA726FFFFA726FFFFA72600000000FF000000FF000000FF9D9D9DFFD6D6D6FF9D9D9D000000000000000000000000FF8E6DC9FF7D55C2FF7D55C2FF7D55C2FF7D55C200000000FFFFB74DFFFFA92CFFFFA726FFFFA726FFFFA72600000000FF323232FF9D9D9DFFD6D6D6FFFBA98FFFFD815A80FD89640000000000000000FF9D80D1FF8E6DC9FF7D55C2FF7D55C2FF7D55C200000000FFFFBD5BFFFFB850FFFFA92CFFFFA726FFFFA72600000000FFA1A1A1FFD7D7D7FFFAE098FFFDAA83FFFF7043FFFD896480FD896400000000FFAD96D7FF9D80D1FF8E6DC9FF7D55C2FF7D55C200000000FFFFBC59FFFFBD5CFFFFB850FFFFA726FFFFA7265FF4F4F4FFD7D7D7FFFAD28EFFFCDE80FFFDDF84FFFC9D6FFFFF7043FFFD815A00000000FFAD96D7FFAD96D7FF9D80D1FF8E6DC9FF7D55C200000000FFFFBC59FFFFBC59FFFFBD5CFFFFB850FFFBC8A0BEF4F4F4FFFBC679FFFFBD5CFFFCCC79FFFDDB6BFFFDD55CFFFC8F5AFFFB9575000000000000000000000000000000000000000000000000000000000000000000000000000000005FF4F4F4BEF4F4F4FFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFCBB4DFFFDD557FFFADA83BEF4F4F400000000FF85B850FF79B23CFF7BB23FFF79B23CFF79B23C00000000FFFDDF87FFFDDF87FFFAE7BAFFF6EFDFFFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFAC975BEF4F4F45FF4F4F400000000FF9CC671FF85B850FF79B23CFF7BB23FFF79B23C00000000FFFEE392FFFAE7BAFFF6EFDFFFFBC679FFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFCBA5BFFF7F7F75FF4F4F40000000000000000FFABCD8AFF9CC671FF85B850FF79B23CFF79B23C00000000FFFEE28DFFF7F0E0FFF9CB8AFFFFBD5CFFFFBD5CFFFFB241FFFFA726FFFFA726FFFCBA5BFFF7F7F7FFFBFBFB000000000000000000000000FFBBD5A2FFABCE8AFF9CC671FF85B850FF79B23C00000000FFFDE291FFF5EDE7FFF9DBC1FFFCC372FFFFB241FFFFA726FFFFA726FFFCBA5BEEF6F6F6FFFBFBFBFFFFFFFF000000000000000000000000FFBBD5A2FFBBD5A2FFABCE8AFF9CC671FF85B85000000000FFFDE291FFF6E4D4FFFAD9BCFFF8D6B6FFFCB044FFFFA726FFFCBA5BEEF6F6F6D6FAFAFABEFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000FFCCC5BFFFF5D1AFFFF9CDA6FFF7D0ACFFFAC273BEF4F4F45FF4F4F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF000000FFC1B8B0FFF6DFCBFFF4ECE5BEF4F4F45FF4F4F4000000000000000000000000000000000000000000000000",
iconStream:function(val){var data=this[val];
	return {count:0, width:20, height:20, read:function(nBytes){return data.slice(this.count,this.count+=2*nBytes)}}}
};
// This adds a button to the Add-on Tools toolbar
app.addToolButton( {
	cName: "changeColorAllTool",
	cLabel: "Colors…",
	oIcon: iconSet_colorsTool.iconStream("button"),
	cTooltext: "Change Colors of Selected Annotations…",
	cEnable: "event.rc = (this.selectedAnnots && this.selectedAnnots.length)",
	cExec: "changeColorsAll(this)" }
);
// This adds a menu item
app.addMenuItem( {
	cName: "changeColorAllMenu",
	cUser: "Change Colors…",
	oIcon: iconSet_colorsTool.iconStream("button"),
	cParent: "Tools", // Change this to "Comments" to put in the Comment menu, etc
	//nPos: 13,
	cEnable: "event.rc = (this.selectedAnnots && this.selectedAnnots.length)",
	cExec: "changeColorsAll(this)" }
);

/* Script to change color of all annotations with a dialog
	only tested on PDF-Xchange Editor v10.0
 * History:
   v1.3 Mar 12, 2024 Add option for hex numbers for colors
   v1.2 Sep 20, 2023 Look at rich contents in all annotations
   v1.1	Jul 04, 2023 Fix to global variable access, revise icon
   v1.0	Jun 20, 2023 Initial release
*/

function changeColorsAll (t) {
	const MAX_SAVED_COLORS = 8; // This is the number of custom colors that will be saved
	const USE_HEX = true; // Set to true to use hexadecimal numbers for the color entry
	
	//  ************************* Begin Color Utility ********************************
	const cUtil = {
		defaultColors: { 
			"Black":color.black,
			"Dark Gray 25%":color.dkGray,
			"Gray 40%":["G",0.4],
			"Gray":color.gray,
			"Light Gray 75%":color.ltGray,
			"White":color.white,
			"Transparent":color.transparent, // only in here because selected items will have it
			"Dark Red":["RGB",139/255,0,0],
			"Red":color.red,
			"Rose":["RGB",1,228/255,225/255],
			"Light Orange":["RGB",1,173/255,91/255],
			"Orange":["RGB",1,104/255,32/255],
			"Gold":["RGB",1,215/255,0],
			"Yellow":color.yellow,
			"Light Yellow":["RGB",1,1,224/255],
			"Lime":["RGB",50/255,205/255,50/255],
			"Pale Green":["RGB",152/255,251/255,152/255],
			"Bright Green":color.green,
			"Sea Green":["RGB",60/255,179/255,113/255],
			"Green":["RGB",0,147/255,0],
			"Dark Green":["RGB",0,85/255,0],
			"Aqua":["RGB",127/255,1,212/255],
			"Teal":["RGB",56/255,142/255,142/255],
			"Turquoise":["RGB",64/255,224/255,208/255],
			"Sky Blue":["RGB",192/255,1,1],
			"Light Blue":["RGB",125/255,158/255,192/255],
			"Cyan":color.cyan,
			"Blue":color.blue,
			"Dark Blue":["RGB",0,0,139/255],
			"Indigo":["RGB",75/255,0,130/255],
			"Midnight Blue":["RGB",0,0,94/255],
			"Plum":["RGB",72/255,0,72/255],
			"Pink":["RGB",1,192/255,203/255],
			"Violet":["RGB",128/255,0,128/255],
			"Magenta":color.magenta,
			"Blue-Grey":["RGB",123/255,123/255,192/255],
			"Brown":["RGB",165/255,142/255,0],
			"Tan":["RGB",210/255,180/255,140/255],
		},
		otherColorText: "Other - Enter:",
		savedCls: {},
		annotCls: {},
		// inititalize saved and annotation colors
		initialize: function(savedColors, annots) {			
			// add the saved colors (clobbers what's in there)
			this.savedCls = savedColors || {};
			// add the annotation colors
			this.annotCls = this.getColors( annots, [] );
		},
		// returns object {colorName:color,...}
		getSavedColors: function( withOtherClr=false, withAnnotCls=false ) {
			let sc = {};
			let gsc = [ this.defaultColors, this.savedCls ];
			// get other colors text
			if (withOtherClr)
				sc[ this.otherColorText ] = "";
			// build color associative array
			// because the key is the color name, if a duplicate color has been saved with a different name, it will show up
			gsc.forEach( cl => Object.assign(sc, cl) );
			// add in annotation colors
			// this checks that it's not already in the list
			if (withAnnotCls) {
				let selClrs = this.findColors( Object.values( this.annotCls ), Object.values( sc ) ); // array
				// doesn't bother to keep the text of the color
				Object.assign(sc, this.colObj(selClrs));
			}
			return sc;
		},
	
		// get list of stroke colors of annotations, and only return those that are not in colorList[]
		// returns object {colorName:color,...}
		getColors: function(annots, colorList){
			let fL = [];
			for (let i in annots) {
				let ann = annots[i];
				
				// get colors from richContents
				if ( ann.richContents && ann.richContents.length )
					fL = fL.concat( ann.richContents.map( rc => rc.textColor ));
				//	default:
				if ( ann.strokeColor ) fL.push( ann.strokeColor );
				if ( ann.fillColor ) fL.push( ann.fillColor );

			};
			
			fL = this.findColors(fL, colorList);

			return this.colObj(fL);
		},
		// returns only the colors in findList[] that are not in colorList[]
		// returns array of colors
		findColors: function(findList, colorList) {
			let addList =[];
			for ( let fc of findList ) {
				let ceq = colorList.some( c => cUtil.equal( fc, c ) );
				if (!ceq) { // not in the list, so add it
					addList.push( fc );
				};
			};
			return addList;
		},
		// add a color to the saved colors list
		// returns object {colorName:color,...}
		addlClrs: function( addColor, currColors=this.savedCls ) {
			// will not add if it's in the default colors list
			let ac = this.findColors( [addColor], Object.values(this.defaultColors));
			// need to see if it's already in the list
			if (ac.length) {
				ac = this.findColors(ac, Object.values(currColors));
			}
			// ac is null if no additional colors
			if (ac.length) {
				this.trimObj( currColors, MAX_SAVED_COLORS-1 );
				// add ac to the currColors list and return
				Object.assign( currColors, this.colObj(ac) );
			}
			return currColors;
		},
		// make a color:value list of colors
		// returns object {colorName:color,...}
		colObj: function(colList) {
			let colOb = {};
			// use the default colors to find actual color names
			let cNames = Object.keys( this.defaultColors );

			for ( let c of colList ) {
				let cN = cNames.find( cc => cUtil.equal( this.defaultColors[cc], c ));
				// temp hack USE_HEX -- **TODO** update as part of dialog
				if ( undefined == cN ) cN = this.colArr256(c, USE_HEX);
				colOb[ cN ] = c;
			};

			return colOb;
		},
		// change the values to 256 based and return string
		colArr256: function(colr, hex=false) {
			let c = [colr[0].toUpperCase()];
			for (let i=1; i<colr.length; i++){
				// need to add 0x to front of hex ?
				c[i] = Math.round( 255*colr[i] );
				if (hex)
					c[i] = util.printf("%x",c[i]).padStart(2,"0"); // util.printf("%02x", number) should pad it, but doesn't seem to work
			}
			return c.join(", ");
		},
		// change 256 based string to color array
		colFromStr: function(colStr, hex=false) {
			let sColor = colStr.split(",");
			sColor[0] = sColor[0].toUpperCase();
			// maybe should check if it's in the correct format?
			for (let i=1; i<sColor.length; i++ ) {
				if (hex) {
					sColor[i] = parseInt(sColor[i],16) / 255;
				} else {
					sColor[i] = sColor[i] / 255;
				}
			}
			return sColor;
		},
		trimObj: function (ob,maxL) {
			// deletes from the front of ob.
			let ol = Object.keys(ob).length - maxL;
			for (let i in ob) {
				// trim length
				if ( ol > 0 ) {
					delete ob[i];
					ol--;
				} else {
					break;
				}
			}
			//return ob;
		},
		// based on the color.equal, but added rounding
		equal : function (c1, c2) {
			if (c1[0] == "G") {
				c1 = color.convert(c1, c2[0]);
			}
			else {
				c2 = color.convert(c2, c1[0]);
			}
			if (c1[0] != c2[0]) {
				return false;
			}
			let nComponents = 0;
			switch (c1[0]) {
				case "G":
					nComponents = 1;
					break;
				case "RGB":
					nComponents = 3;
					break;
				case "CMYK":
					nComponents = 4;
					break;
				default: ;
			}
			for (let i = 1; i <= nComponents; i++) {
				if ( Math.round(c1[i]*255) !=  Math.round(c2[i]*255) ) {
					return false;
				}
			}
			return true;
		}
	}
	
	//  ************************* Begin Object Utility ********************************
	const obUtil = {
		// get object with prop == val
		getObj: function ( obj, prop, val ) {
			let found;
			if  ( obj[prop] == val ) {
				return obj;
			} else {
				if (obj.elements) {
					for (let e in obj.elements) {
						found = this.getObj( obj.elements[e], prop, val );
						if (found) break;
					}
				}
			};
			return found;
		},
	}
	
	//  ************************* Begin Dialog ******************************** 
	const colorDialog = {
		colors:[],
		colorKeys:[], 	// to hold all the colors for the dropdowns (keys - text)
		data:[],		// dialog results
		selColors:[],	// selected color (index on colors or colorKeys)
		nClrs: () => colorDialog.selColors.length ,		// number of selected colors
		//nAnns: 0,

		initialize: function (dialog) {
			let dLoad = {}; //cUtil.updateObject( {}, this.data ); // don't change data
			// need to deal with the popups
			for (let i=0;i<this.nClrs();i++) {
				let butn = util.printf("%02d", i);
				dLoad[ "cE"+butn ] = this.colorKeys[ this.selColors[i] ];
				dLoad[ "cC"+butn ] = cUtil.colArr256( this.colors[ this.selColors[i] ], USE_HEX );
				dLoad[ "cP"+butn ] = this.getListboxArray( this.colorKeys, this.selColors[i] );
			};
			dialog.load( dLoad );
		},
		commit:function (dialog) { // called when OK pressed
			this.data = dialog.store();
			// need to deal with the popups
			for (let i=0;i<this.nClrs();i++) {
				let butn = util.printf("%02d", i);
				this.data[ "cP"+butn ] = this.getIndex( this.data[ "cP"+butn ] );
			};
			// return "ok"
		},
		// returns the index number of the first item with positive number value
		getIndex: function (elements) {
			for (let i in elements) {
				if ( elements[i] > 0 ) {
					return elements[i]-1; //i ; the index is the text of the dropdown
				}
			}
		},
		
		// create object array suitable for the listbox. selItem is index
		// returned array is {"Displayed option":-order,...}
		getListboxArray: function(vals, selItem) {
			let sub = {};
			for (let i=0; i<vals.length; i++) {
				// positive number if selected
				sub[vals[i]] = ((selItem == i)?1:-1)*(i+1);
			}
			return sub;
		},
		// change to the custom color input box -- needs to be called from each box
		// butn is formatted util.printf("String format: %02d", n)
		clrInput: function (dialog,butn) { 
			let results = dialog.store();
			let pickedIndx = this.colors.findIndex( c => cUtil.equal( c, cUtil.colFromStr( results["cC"+butn], USE_HEX ) ));
			if ( pickedIndx < 0 ) pickedIndx = 0;
			let dLoad={};
			dLoad["cP"+butn] = this.getListboxArray( this.colorKeys, pickedIndx );
			dialog.load( dLoad );	
		},
		clrDropdn: function (dialog,butn) { // change to the dropdown
			let results = dialog.store();
			// update the custom color box
			let pickedClr = this.colors[ this.getIndex( results["cP"+butn] ) ];
			if ( pickedClr ) { // should be falsy "" for othercolor
				let dLoad={};
				dLoad["cC"+butn] = cUtil.colArr256( pickedClr, USE_HEX );
				dialog.load( dLoad );
			}
			//dialog.enable({"cClr": (results["hClr"][cUtil.otherColorText] > 0)});
		},
		description: {
			name: "Replace Color", // Dialog box title
			align_children: "align_left",
			width: 380,
			//height: 200,
			elements:
			[{	type: "cluster",
				name: "Colors", 
				align_children: "align_left",
				item_id: "Ctnr", // this name is used to get the container for the dropdowns
				elements:
				[{	type: "view",
					align_children: "align_row",
					name:"Headings",
					//item_id: "Ctnr", 
					elements:
					[
					{	type: "static_text",
						name: "Current Color",
						width: 100,
						alignment: "align_center",
						bold: true
					},
					{	type: "static_text",
						name: "|",
						width: 5
					},
					{	type: "static_text",
						name: "Select New Color",
						width: 100,
						bold: true
					},
					{	type: "gap",
						width: 20 // for the dropdown arrow
					},
					{	type: "static_text",
						name: "Enter Color",
						alignment: "align_fill",
						//width: 120
						bold:true
					}]
				}
				]
			},			
			{	type:"static_text",
				name: "The first element in the comma separated list is a string denoting the color space \ntype. The subsequent elements are numbers that range between zero and 255 inclusive. \nFor example, the color red can be represented as [RGB, 255, 0, 0]. \nColor Space options are: \nG (Gray - single value 0 is black), RGB (3 values), CMYK (4 values).",
				font: "palette",
				alignment: "align_fill",
				width: 380,
				height:70,
			},
			{	alignment: "align_right",
				type: "ok_cancel",
				ok_name: "Ok",
				cancel_name: "Cancel"
			}
			]
		}
	};
	// menu items
	class MenuItem {
		baseMenu = {	type:"view",
			align_children:"align_row",
			//item_id: "cTxx", // typical container
			elements:
			[{	type:"static_text",
				name: "Existing Color", // for the existing color
				width:100,
				alignment: "align_center",
				item_id: "cExx"
			},
			{	type: "static_text",
				name: "|",
				width: 5
			},
			{	type: "popup",
				//alignment: "align_fill",
				width: 100,
				item_id: "cPxx"
			},
			{	type: "edit_text",
				//width:125,
				alignment: "align_fill",
				item_id: "cCxx",
			}]
		};
		xx;
		constructor ( num, dia ) {
			let xx = this.xx = util.printf("%02d", num);
			// relabel
			this.baseMenu.elements.forEach( e => 
				e.item_id = (e.item_id ? e.item_id.substring(0,2)+xx : null ));
		};
		// fns = { diaID:func,... }
		setHandlers ( dia, fns ) {
			let xx = this.xx;
			for ( let f in fns ) {
				dia[f+xx] = function(dialog) { dia[fns[f]]( dialog, xx ) };
			};
		};
		get() {
			return this.baseMenu;
		}
	};
	

// Logic:
  // Get colors of all selected annotations
  // Build menu > curr color > new color
  // Check if any of the colors are changed & dialog "OK"
  // Make a list of old color > new color
  // For each annotation
  //    go through old color > new color list
  //	change all colors of that annotation with one .setProps()

	// get all annotation objects - try to use selected annotations
	let annArr = t.selectedAnnots;
	
	if (!annArr || !annArr.length){
		if ( t.getAnnots() ) { // ie there are some annotations in the document
			var noAnSel = app.alert({
				cMsg: "No Annotations selected, change all annotations in the current document?",
				cTitle: "Changing ALL Annotations",
				nIcon: 1, nType: 1 });
		}
		if ( noAnSel == 1 ) {
			annArr = t.getAnnots();
		} else {
			return "Nothing Selected";
		}
	}
	// try to get global variables
	let savedPrefs = CHANGE_COLORS_PREFS.get();
	if (!savedPrefs) {
		// defaults
		savedPrefs = {
			savedColors:{}
			//dialog:{},
		};
	};
	// saved values to the dialog
	//for (let d in savedPrefs.dialog)
	//	colorDialog.data[d] = savedPrefs.dialog[d]; // shallow copy

	// get the annotation colors
	cUtil.initialize( savedPrefs.savedColors, annArr );

	// initialize dialog
	//colorDialog.nAnns = annArr.length;
	let allColors = cUtil.getSavedColors( true, true );
	colorDialog.colors = Object.values( allColors );
	colorDialog.colorKeys = Object.keys( allColors );
	
	// build dialog dropdowns
	let drContainer = obUtil.getObj ( colorDialog.description, "item_id", "Ctnr" );
	drContainer.name = annArr.length + " Annotations Selected";

	// array of the annotation color values
	let annotColors = Object.values( cUtil.annotCls );
		
	for (let x in annotColors) {
		// get the annotation colors index to the colors list
		colorDialog.selColors[x] = colorDialog.colors.findIndex( c => cUtil.equal( c, annotColors[x] ));
		
		let dia = new MenuItem( x, colorDialog );
		dia.setHandlers( colorDialog, { "cP":"clrDropdn", "cC":"clrInput" } );
		drContainer.elements.push( dia.get() );
	};

	//  *** run the dialog ***
	let result = app.execDialog(colorDialog);
	
	if ("cancel" == result) return result;

	// make list of changed colors
	let chCols = [];
	for (let x in annotColors) {
		// compare the new to existing colors
		let xx = util.printf("%02d", x);
		// ** todo ** update in dialog?
		let newClr = cUtil.colFromStr( colorDialog.data["cC"+xx], USE_HEX );
		if ( !cUtil.equal( annotColors[x], newClr )) {
			chCols.push( {"oldCl":annotColors[x],"newCl":newClr} );
		};
	};

	if ( !chCols.length ) return "No colors changed";
	
	annArr.forEach( ann => {
		let revs = {};
		// get colors from richContents
		if ( ann.richContents && ann.richContents.length ) {
			let changed = false;
			let spans = [];
			for (let s in ann.richContents) {
				spans[s] = ann.richContents[s];
				for (let c of chCols) {
					if ( cUtil.equal( spans[s].textColor, c.oldCl )) {
						changed = true;
						spans[s].textColor = c.newCl;
					}
				};
			};
			if (changed) revs["richContents"] = spans;
		}
		// get colors from array items props
		let props = [ "strokeColor", "fillColor" ];
		for (let prop of props) {
			for (let c of chCols) {
				// property may not exist for this annotation
				if ( ann[prop] && cUtil.equal( ann[prop], c.oldCl ))
					revs[ prop ] = c.newCl;
			};
		};
		// apply the revisions
		if (Object.keys(revs).length) ann.setProps( revs );
	});

	// save the custom colors
	for ( let sc of chCols ) {
		// only add if the strokeColor isn't part of the default and saved colors
		Object.assign( savedPrefs, {"savedColors": cUtil.addlClrs( sc.newCl, savedPrefs.savedColors)} );
	};
	// update global variable
	CHANGE_COLORS_PREFS.set( savedPrefs );

	return result;
}

// need trusted function to store preferences
const CHANGE_COLORS_PREFS = new class {
	constructor(name) {
		this.get = app.trustedFunction(() => {
			app.beginPriv();
			if ( global[name] )
				return JSON.parse( global[name] );
			});
		this.set = app.trustedFunction( value => {
			app.beginPriv();
			global[name] = JSON.stringify( value );
			global.setPersistent( name, true);
			});
	}
}("CHANGE_COLORS_PREFS");
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

oh, and I agree: If this were a built-in tool, it would have access to the color picker, and be able to show a color square on the dialog box. As far as I know, there's no way to put images or colors on the dialog boxes that we can generate with javascript.

Here's my wish: That this tool were built-in and could also work on the content of the document, not just the annotations.
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Mathew wrote: Tue Mar 12, 2024 10:34 pm oh, and I agree: If this were a built-in tool, it would have access to the color picker, and be able to show a color square on the dialog box. As far as I know, there's no way to put images or colors on the dialog boxes that we can generate with javascript.

Here's my wish: That this tool were built-in and could also work on the content of the document, not just the annotations.
I have already asked about this, and their response was that Javascript can not affect base content (content of the document)

However, if there is some workaround I would also love to be able to change properties of selected base content in a similar way.

After all, your script can not change things like; thickness, font color, font size etc....
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Other reasons to make an inbuilt tool:

(ofc. to see the colors in question visualized, like Mathew said)

but also to be able to undo the change with Ctrl+Z activate it with a keyboard shortcut etc...
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster, Mathew,

Thanks for the above discussion. For now there are no plans to make this a built in tool, so I hope it works for you as a JS one @MedBooster!



Kind regards,
Stefan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Is it possible to activate your script with a keyboard shortcut?


PS: RGB still works fine, but it seems const USE_HEX = true does not really make a difference. Is the current color still supposed to be displayed in RGB?
Also, is it actually not possible to have any color in such javascript menus? To add a square... or have the text color match the color code in RGB/HeX?

With USE_HEX set to True it seems the color just turns to a shade of black, are you supposed to input it with or without #?
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster,

The customer buttons created for JS code can not have keyboard shortcuts assigned to them I am afraid.
As for the RGB question - is that for Mathew or ourselves?

Kind regards,
Stefan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Tracker Supp-Stefan wrote: Thu Mar 14, 2024 10:58 am Hello MedBooster,

The customer buttons created for JS code can not have keyboard shortcuts assigned to them I am afraid.
As for the RGB question - is that for Mathew or ourselves?

Kind regards,
Stefan
I'm referring to simply running the script / opening the window, not shortcuts for converting particular colors etc...
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Change annotation colors tool

Post by Tracker Supp-Stefan »

Hello MedBooster,

Yes - I understood that part - there is no way to assign a custom shortcut to running custom scripts I am afraid.

Kind regards,
Stefan
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Tracker Supp-Stefan wrote: Thu Mar 14, 2024 11:14 am Hello MedBooster,

Yes - I understood that part - there is no way to assign a custom shortcut to running custom scripts I am afraid.

Kind regards,
Stefan

Even from within the script itself? Could you position a keyboard shortcut button for it multiple places? One in the add-on tab and one in the navigation bar for example?

Still waiting eagerly for HeX to work in Mathew's script. I understand he might be working on other ones, so for now I'll just convert them.

Thank you, and happy Easter. 🐣
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

MedBooster wrote: Mon Mar 25, 2024 4:17 pm Even from within the script itself? Could you position a keyboard shortcut button for it multiple places? One in the add-on tab and one in the navigation bar for example?

Still waiting eagerly for HeX to work in Mathew's script. I understand he might be working on other ones, so for now I'll just convert them.
Medbooster: I posted update code above - save it as a js file and it should work with Hex values. The limitation is that you can't switch between hex and decimal within the script yet.
viewtopic.php?p=177150#p177150

As far as I know there's no javascript way to assign keyboard shortcuts. It may be possible to run the script with AutoHotkey though? I know that's customization on top of customization...
User avatar
TrackerSupp-Daniel
Site Admin
Posts: 8624
Joined: Wed Jan 03, 2018 6:52 pm

Re: Change annotation colors tool

Post by TrackerSupp-Daniel »

Hello, Mathew

I also do not know of any way to customize hotkeys via the JS, I don't think its possible, as that is something which would be specific to each application.
JS generally doesn't have such low level access to the applications (and even if it did, there is no way know that every app would understand/store the hotkeys in the same way, making the JS highly unreliable.

Kind regards,
Dan McIntyre - Support Technician
Tracker Software Products (Canada) LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

Hi Mathew, yes I have tried the new version of the script a couple of times now, with HeX set to true, but still only HeX values appear.

In my opinion it would be better to see both HeX and RGB at the same time.

image.png

Basically nothing seems to change after setting it to true.

Are you supposed to input the code with or without #?
With the color fe4a49 for example, it does not matter whether I put it with or without "#", it just changes the color to black.

Is the new version supposed to display the HeX code of the current color as well?
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
Mathew
User
Posts: 239
Joined: Thu Jun 19, 2014 7:30 pm

Re: Change annotation colors tool

Post by Mathew »

MedBooster wrote: Tue Mar 26, 2024 10:21 pm Are you supposed to input the code with or without #?
With the color fe4a49 for example, it does not matter whether I put it with or without "#", it just changes the color to black.

Is the new version supposed to display the HeX code of the current color as well?
Ah, I misunderstood what you were looking for. In this version, if you leave
const USE_HEX = true;
then the numbers themselves are in hexadecimal format (ie 255=FF). I didn't update the instructions at the bottom of the dialog box but in hex notation, each number is between 00 and FF instead of 0 and 255.

with the color #fe4a49 this would need to be entered as RGB, fe, 4a, 49

but I think I now understand what you are looking for: Would you like to be able to paste fe4a49 directly in there?
MedBooster
User
Posts: 1070
Joined: Mon Nov 15, 2021 8:38 pm

Re: Change annotation colors tool

Post by MedBooster »

aaah now I see. Thank you!

Yes that's what I would prefer (maybe others?), but it's not a big deal.
Wishlist
Bookmarks with page numbers
Optional fixed small icon size in the toolbar
Shift to UNLOCK aspect ratio/i]
Allow more "toolbars" to the title bar
AltGr issues with character input and keyboard shortcuts
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Change annotation colors tool

Post by Tracker Supp-Stefan »

:)
Post Reply