What responder catches undo action? - cocoa

I have a view that handles undo and redo. For a specific state I change first responder from the view to the view's window. Now in that state I expect the validateMenuItem: method in the window's delegate to check the undo menu item.
This works when I close the window. But when the window is visible some other responder deals with the undo action.
My guess is that it's the window controller? But as this is a non-document based app I haven't implemented one manually. Will I have to create a custom window controller? And if so, what's the simplest way to do that?

Found the answer here: http://www.cocoabuilder.com/archive/cocoa/307917-validatemenuitem-not-called-for-undo-menu-item.html
Configuring the Undo menu item with action 'undo:' tells the
frameworks that this is the undo menu item, so it becomes one
element of a standard undo UI mechanism implemented in NSWindow. Under
these circumstances, the menu item (and especially its validation)
isn't yours to mess with.
If you want to take implement the entire mechanism yourself, then you
should use a custom action such as 'myUndo:' for the Undo menu item.
That means, as far as the frameworks know, you app doesn't have
(standard) undo, and the action/validation should work in the normal
way.

Related

How to keep a hidden view in responder chain?

I have a NSSplitViewController and in one of the items I have multiple buttons with keyboard shortcuts.
Once the user hides the item, the shortcuts don't fire.
Is there any way to keep the buttons in the hidden view as part of the responder chain?
Sounds like the simple answer is no, according to Apple's docs. A simple workaround, however, might be to move the buttons out of the visible area by, say, shifting their bounds right by 10,000 or so. If they are in a scrollview/clipview that would expand to show the items in their new position, then this would not work so well, but if they aren't, it ought to work fine. If they are in a scrollview, then you might find a way to make them completely transparent, to achieve a similar effect.
That said, perhaps it is worth considering whether you have the right design in the first place, since having buttons that are not visible respond to key events is a questionable design from a user-interface perspective (as reflected by the fact that Apple tries to prevent it). Maybe those keyboard events should really be getting handled by a view higher in the view hierarchy, or by the window, or some such entity?

Can NSDatePicker have a contextual menu?

Ive been adding contextual menus to an OSX app I'm developing, and have successfully created a menu for a table view. However I'm having problems adding a contextual menu to a NSDatePicker. I've connected the 'menu' outlet to a NSMenu, but right clicking on the NSDatePicker doesn't bring up the menu.
I've checked the menu property on the date picker and it appears to be set correctly.
Is there an inherent issue with trying to create a contextual menu for a NSDatePicker? If so is there a way to get this working (short of reimplementing NSDatePicker)? I'd also prefer to avoid having an extra button to display the menu if at all possible - right clicking on the date picker is the obviously intuitive way this should work.
On OS X 10.9.5, class-dump shows that NSDatePicker overrides -rightMouseDown: (as well as -rightMouseDragged: and -rightMouseUp:). I'm guessing it doesn't call through to super and so is (accidentally?) blocking the contextual menu.
First, does right-dragging in a date picker do something unique? I've not been able to see it, but who knows. It may depend on the datePickerStyle and/or datePickerMode.
Also, I don't see an override of -mouseDown:. So, I bet that Control-clicking would bring up the contextual menu.
I recommend that you accept this limitation. However, if you really want to force the issue, you'll probably need to subclass NSDatePicker and override the -rightMouse... methods. For -rightMouseDown:, you could call NSMenu* menu = [self menuForEvent:theEvent] and, if that returns a menu, call [NSMenu popUpContextMenu:menu withEvent:theEvent forView:self]. Otherwise, do nothing (i.e. don't call through to super).
For the other two methods, you should probably just do nothing to prevent the superclass methods from getting confused by seeing right-drag and right-mouse-up events when it didn't get the right-mouse-down event.

FirstResponder as delegate for NSToolBar

I have a Mac app that consists of a window with a variable number of panes in it, each containing a tableview. The window has a toolbar with buttons, and I want the VC for the currently selected pane to handle validating the toolbar items, as well as being target for their actions.
If I could set first responder as delegate for the toolbar, this would be handled automatically, so my question is if that is possible! I have obviously googled around for this and some articles seem to hint that it is possible, but IB doesn't seem to let me do it.
An NSWindowController subclass would be better suited for this, that is the toolbar's delegate (it's natural role anyway) and can talk with the currently selected pane, using a custom protocol to decide on business logic.
Same goes for the UI/Menu action handlers; the window controller is perfect for this and your design will fit within it well.
It's not really got anything to do with the first responder as you are interested in the currently selected pane, not the first responder.

Facing issue with internationalize MainMenu.xib for Cocoa based Mac OS X Application

I am working in a Cocoa based Mac OS X project and facing one issue with internationalize MainMenu.xib.
In the menu items, all titles are need to be internationalized programmatically. All the menu items like “cut”, ”copy”, ”paste” can be internationalized using setTitle except the undo and redo menu item title. Adding to this, after typing anything in the text fields of the project forms, the undo menu item title dynamically changed to “Undo Typing”. The same happens for “Redo” also.
I can set the titles of other menu and menuitems' title using,
[[[[NSApp mainMenu] itemAtIndex:1] submenu]setTitle:#"Edit_Test"]
for MainMenu.xib "Edit" menu and similarly,
[[[[[NSApp mainMenu] itemAtIndex:1] submenu]itemAtIndex:4]setTitle:#"Copy_Test"]
for NSMenuItem "Copy" which is in under "Edit" menu.
But If I use the same piece of code,
[[[[[NSApp mainMenu] itemAtIndex:1] submenu]itemAtIndex:0]setTitle:#"Undo_Test"]
the menuItem title still remain as "Undo"
NSUndoManager provides the methods undoMenuItemTitle and redoMenuItemTitle, but NSUndoManager does not send the -setTitle: messages to the "Undo" and "Redo" menu items.
So how can I track that dynamic change in title and make that "Undo Typing" internationalized also?
Is it possible to manually get the First responder of the MainMenu.xib and from that get the undomanager object? So that i can unbind the undo action that is currently present in the first responder with the undo menu item and perform undo operation manually or is it possible to just change the title programmatically without doing all these.
Please let me know if any one had come across this problem and resolved the issue.
Make a subclass of NSUndoManager and override the undoMenuTitleForUndoActionName: method and the redoMenuTitleForUndoActionName: method. Create instances of this subclass for each document (or managed object context, or other thing) that needs an undo manager.

NSTextFinder action on NSTextView

I'm trying to capture all the NSTextFinderClient calls on my custom NSTextView subclass.
The show action is called on my -(void)performTextFinderAction:(id)sender override, but for find next, find previous, etc. it's not called.
Any ideas?
Thanks!
Edit:
If you create a new project and drag an NSTextView from interface builder, command-g and command-shift-g (find next and find previous) don't work when the find bar is first responder.
Why is this?
I need a custom subclass of NSTextView to respond to the find bar for every event.
I searched in the Apple's TextEdit source code because with TextEdit, the standard search bar within the Text View works fine for command-G (and other shortcuts) even the search field is the first responder.
I found the solution.
Go to your nib for the main menu, and select the "Find" (and related) menu items. They should be bound to the default action called "performFindPanelAction:." Now unbind them and bind to "performTextFinderAction:" of the First Responder instead.
You may not find that action in the First Responder's action list. So you need to add it by yourself in the First Responder's attributes inspector pane.
This was meant by the document below saying
Before OS X v10.7, the default action for these menu items was performFindPanelAction:. Whenever possible which you should update your implementation to use this new action.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/#//apple_ref/occ/instm/NSResponder/performTextFinderAction:
The find bar communicates privately with the client's NSTextFinder instead of calling NSResponder's -performTextFinderAction:. This is necessary to allow find to work when something besides the client has key focus.
What are you trying to accomplish?

Resources