Aperture Plugin: Preventing Illegal Path Characters

cocoasmall
Since the prefix and postscript strings will be going into a path, I also want to prevent the user from entering characters such as / and : that could cause unintended actions. There is no delegate method I can add to a text field to do this. Instead, a different class is used: a text formatter.

A text formatter can be attached to a text cell. Once attached, it can intervene in the formatting of the text to modify what the user sees. A phone number formatter would automatically add brackets and spaces as a number were entered, for instance. A formatter can also change the color and style of the text, and add and remove characters.

Since none of the supplied formatters do what I want, I will have to write my own. And to do that I have to create a new formatter class as a subclass of NSFormatter, the abstract base class that all formatters descend from.

The new formatter will be called BTValidPathElementFormatter and will prevent forward slash and colon characters from appearing, and optionally disallow leading periods and hyphens. Leading periods in file names make the file invisible in the Finder and that would almost certainly be unintended. Leading hyphens are not valid in a file name.

To create my new class in XCode I use File > New File and select Objective C class. Then I give it a name and make sure it is added to my project:
rwok83
Then in the header file, I add the prototypes for the necessary methods, and add my own methods and ivars for handling the leading periods and hyphens:
rwok91
The -isPartialStringValid: method allows me to figure out what was just added to the string, and then act accordingly to adjust the string and the current selection.

I need -init and -dealloc methods for my class. I use the -init method to initialize the superclass and up the default state of my ivars:
rwok92
And I have to provide methods for changing the period and hyphen options:
rwok93
These three methods are filled in with what is basically template code:
rwok94
And finally here are the guts of the class: the code that disallows the characters. The first part sets up a character set that will be used to compare against the string in the text field. Then two easy cases are dealt with quickly:
rwok95
The code uses NSRange structures to keep track of the current selection. Next, periods and hyphens and disallowed:
rwok96
I'm not certain if the unichar cast is needed, but I did notice that the type returned by characterAtIndex: is of type unichar, so put it in to be on the safe side. Finally I look for the illegal characters in the text that was inserted. I can figure out what was added by comparing the previous and current selections:
rwok97
And that is it for the new class. I have to make some changes in Random_Wok so that the new formatter is attached to the fields and set up correctly. I add this code to -willBeActivated:
rwok98
It creates an instance of the formatter for each of the two fields that need formatting. Additionally the prefix formatter is set to reject hyphens and periods. Finally the formatters are attached to the NSCells associated with the NSTextFields using -setFormatter.

A delegate method to NSControl -control:didFailToValidatePartialString:errorDescription is called whenever the formatter returns NO. Since Random_Wok is already a delegate of the three text fields, this will be called. By coding it to beep, I can give the user audible feedback that the key press is not permitted:
rwok99
And the code works. The prefix field will not accept leading periods or colons and both the prefix and postfix fields reject forward slashes and colons.

The other parts of this series can be found via the Cocoa page.
The Bagelturf site welcomes Donations of any size