I wanted to validate toolbar items so as to disable a button if nothing is selected in the table.
The following works, but I don’t know why:
The toolbar item’s NSButton has a binding for Enabled set to ‘Array Controller’ with:
Controller Key: Selection
Model Key Path: anything
Value Transformer: NSIsNil.
It happens to work great, but it would be much better if I knew why! Is this reliable? The model key path must be there, but it can be an arbitrary invalid string. Hmm.
I did try to use the methods ‘validateUserInterfaceItem:’ and ‘validateToolbarItem:’ but none of them seem to work for a regular button in the toolbar. That’s why I turned to bindings.
(validateToolbarItem: says it only works for image items, and validateUserInterfaceItem: only seem to work for menu stuff, such as popup menus. But maybe someone knows of ways around that.)
I think this works because the value of array controller.anything will be nil when you select something in the table since anything is not defined, and thus will always be nil. When you haven’t selected anything, there isn’t any selection and array controller.selection returns “no selection”, which not being nil makes your button is disabled.
I don’t know how reliable this is, but the way you should do it, I think, is to bind the button’s enabled to array controller.selection.key with a Value Transformer of NSIsNotNil, where “key” is any of the Model Key Paths that you used to bind your table columns. Another way to do it is to bind your button’s enabled to array controller.canRemove and then you don’t need any model key path or value transformer (this works because the array controller can only remove an entry if something is selected).
Finally I also figured out how to validate segments of NSSegmentedControl in toolbar items:
Apple has documented it, but it is often really difficult to find the right place to read about it.
First, validateUserInterfaceItem_ seemed like a good thing, but it won’t do toolbar items. Then I found validateToolbarItem_ which seemed like a good thing, but it says it only does image items. Since I use image items (NSAddTemplate and NSRemoveTemplate) I thought that would be ok, but I realized that those are set for the NSSegmentedControl, so that does not count. I almost gave up. But finally I found a description on how to do it: “Validating Toolbar Items”, which is at http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Toolbars/Tasks/ValidatingTBItems.html#//apple_ref/doc/uid/20000753-BAJGFHDD
In essence: Subclass NSToolbarItem and use this class for those items that need “special” validation. Implement validate() and do some checks and then use setEnabled_forSegment_. Not difficult at all, but it was difficult to find out…
(Note: The NSSegmentedControl (and NSSegmentedCell) has a bindings entry for Enabled, but that is for the whole control, not for each cell, so bindings can’t be used, which is ok with me since real validation code can be so much more precise than bindings.)