Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

BadWolf13

macrumors 6502
Original poster
Dec 17, 2009
271
0
Ok, got a program with two XIB files. Now, I want something happening in my secondary XIB file to affect the "enabled" status of some of the menu items in MainMenu.XIB. I created 3 NSMenuItem outlets in the windowController subclass for my seconary XIB file in the hopes that I could connect them using FirstResponder. However, that's not working.

Now I know I could move the outlets to the "Controller" class and use Notifications, but I'm wondering if there's a way to do this without notifications.

So, does anyone have any suggestions, or do I have to do the notification thing.
 

BadWolf13

macrumors 6502
Original poster
Dec 17, 2009
271
0
Thanks for the idea, but it's not working. The documentation says that the validateMenuItem method has to be placed in the target of the menu item in question. Here's the kicker, the target of these three methods is FirstResponder. Now I placed the validateMenuItem method in the same class that the responding methods are listed in, but the method isn't even being accessed by the program. Anything special I have to do in this case?
 

Sydde

macrumors 68030
Aug 17, 2009
2,552
7,050
IOKWARDI
Thanks for the idea, but it's not working. The documentation says that the validateMenuItem method has to be placed in the target of the menu item in question. Here's the kicker, the target of these three methods is FirstResponder. Now I placed the validateMenuItem method in the same class that the responding methods are listed in, but the method isn't even being accessed by the program. Anything special I have to do in this case?

For your future reference, in case you do not already understand what the First Responder in a xib file is, it is just a way to set the action of an object without setting its target: when you connect to First Responder, the target is set to nil, meaning the responder chain will be followed to find a target that responds to the action.

Which raises the question: where are the action and validateMenuItem methods? Is the class in which they reside a descendent class of NSResponder? If not, you need to put them into a class that is, that is in the responder chain. Perhaps look at the documentation on the responder chain.
 

BadWolf13

macrumors 6502
Original poster
Dec 17, 2009
271
0
Thank you Sydde,

I can confirm a couple of things for you. First, the class that contains the target actions for these menu items is a subclass of NSWindowController, so yes, it does inherit from NSResponder, and yes, it is in the responder chain. It is the same class that I put the validateMenuItems method into. I wash hoping that was the right choice, but when I placed a breakpoint into it, the program never reaches it.
 

Sydde

macrumors 68030
Aug 17, 2009
2,552
7,050
IOKWARDI
Well, I would just code the outlets. The code (if it is in the window controller) would look something like

Code:
- (id)initWithWindowNibName:(NSString)windowNibName {
     NSMenu          *menuOfInterest
     [super initWithWindowNibName:windowNibName];
     // tagForMenu is defined in the .h file and set in IB
     menuOfInterest = [[[NSApp mainMenu] itemWithTag:tagForMenu] submenu];
     if ( nil != menuOfInterest ) {
          // tagForItem is defined in .h and set in IB
          // menuItemOutlet is an ivar
          menuItemOutlet = [menuOfInterest itemWithTag:tagForItem];
          // for as many outlets as you need to connect
     }
}

I always use tags to make it easier to localize and/or modify the app. You could put code similar this in an -awakeFromNib or -windowControllerDidLoadNib method in any object if it makes more sense to do that. Assuming you are writing a document-based application, the code that validates the menu probably should check to make sure it is the key window.
 

BadWolf13

macrumors 6502
Original poster
Dec 17, 2009
271
0
Thanks dude, I figured out how to fix my validateMenuItem method after all. I had it using an If based on the title of the menuItem, which for some reason didn't work. Changed it to use tags, such as below.

Code:
-(BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
	NSLog(@"Validating Menu Item: %@", [menuItem title]);
	
	if ([[self window] isKeyWindow]) {
		ItemDetailsController *wc = [[self window] windowController];
		
		if ([menuItem tag] == 42) {
			return ![wc openForEditing];
		}		
		if ([menuItem tag] == 43) {
			return [wc openForEditing];
		}
	}
	
	return YES;
}

Now one question, if I wanted to define a constant like tagForMenu, instead of using straight numbers, how would I do that?
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Easiest way is with #defines:

Code:
#define MyMenuItemTag 42

Then just use MyMenuItemTag wherever you'd use 42.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.