Inserting text at cursor, and more

Hi Folks,

I’d like my text field to have a row of buttons above it, just like the ones you have on this site when you’re writing a message, so that when you click them it adds BB Code to the box, either at the cursor, or on either side of what you’ve selected. The only thing I’ve thought of is a way to add something to the end of the text field, by copying it’s contents, and then pasting it back + the thing you want to add, but that’s not what I’m after.

Just one more question, I’d also like to know how to open a URL in the user’s default browser.

Thanks for your help.

From Standard Additions:

open location "http://bbs.applescript.net" 

Hi Lambo,

here’s how to insert text in TextFields:


on insertString(theTextField, theString)
	set txEd to (call method "currentEditor" of theTextField)
	set selectedRange to (call method "selectedRange" of txEd)
	call method "replaceCharactersInRange:withString:" of txEd with parameters {selectedRange, theString}
end insertString

on insertStringAtStartOfText(theTextField, theString)
	set txEd to (call method "currentEditor" of theTextField)
	call method "replaceCharactersInRange:withString:" of txEd with parameters {{0, 0}, theString}
end insertStringAtStartOfText

on insertStringAtEndOfText(theTextField, theString)
	set txEd to (call method "currentEditor" of theTextField)
	set theEnd to length of (get string value of theTextField)
	call method "replaceCharactersInRange:withString:" of txEd with parameters {{theEnd, theEnd}, theString}
end insertStringAtEndOfText

on insertStringAtStartOfSelection(theTextField, theString)
	set txEd to (call method "currentEditor" of theTextField)
	set selectedRange to (call method "selectedRange" of txEd)
	set insertionPoint to item 1 of selectedRange
	call method "replaceCharactersInRange:withString:" of txEd with parameters {{insertionPoint, insertionPoint}, theString}
end insertStringAtStartOfSelection

on insertStringAtEndOfSelection(theTextField, theString)
	set txEd to (call method "currentEditor" of theTextField)
	set selectedRange to (call method "selectedRange" of txEd)
	set insertionPoint to item 2 of selectedRange
	call method "replaceCharactersInRange:withString:" of txEd with parameters {{insertionPoint, insertionPoint}, theString}
end insertStringAtEndOfSelection

Thanks Dominik! That looks great. I’ll try it once I’ve had a good night’s sleep.

I forgot to mention: These scripts will result an error if the text field is not selected.
Maybe you’d better add an ‘on try’:

on insertString(theTextField, theString)
	try
		set txEd to (call method "currentEditor" of theTextField)
		set selectedRange to (call method "selectedRange" of txEd)
		call method "replaceCharactersInRange:withString:" of txEd with parameters {selectedRange, theString}
	on error
		-- the text field is not selected -> there is no currentEditor of theTextField ...
	end try
end insertString

or, if you want to insert at the end of text in this case:

on insertString(theTextField, theString)
	try
		set txEd to (call method "currentEditor" of theTextField)
		set selectedRange to (call method "selectedRange" of txEd)
	on error
		-- it's not selected -> insert at the end:
		call method "makeFirstResponder:" of (call method "window" of theTextField) with parameter theTextField
		set txEd to (call method "currentEditor" of theTextField)
		set theEnd to length of (get string value of theTextField)
		set selectedRange to {theEnd, theEnd}
	end try
	call method "replaceCharactersInRange:withString:" of txEd with parameters {selectedRange, theString}
end insertString

Oh, well isn’t that a bit of a problem, because as soon as they click on the button, it will unselect the text field?

Before the code that inserts the text, add this:

set first responder of window 1 to text field 1 of window 1

That’ll set the focus to the text field, and when the rest of the script runs, the text should be added.

Lambo,

no - the text field won’t loose it’s ‘currentEditor’ when a button is clicked. This will only happen if the user starts editing an other text field, text view, table cell etc. in the same window

As for gonfuko’s idea - I am pretty sure adding this line will result in loosing your current selection/cursor position.