selector class

Hi everyone, I’m back (been a while), almost finished my Dialog Maker app which I will be putting on the App Store :slight_smile:

I have come to one problem:

  • (NSMenuItem *)insertItemWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)keyEquiv atIndex:(NSInteger)index

Please could someone tell me how to pass the aSelector which in this case is ‘subremgen_(sender)’. I could use the popup button’s action and find the item selected but this would be awkward here.

Thanks

Richard

You just put the selector name in quotes and use colons instead of underscores, so “subremgen:” (I’m assuming you’re doing this in ASOC rather than objective C).

Ric

Thanks I had already tried that and it didn’t work again, here’s the code (sorry it’s messed up I have the very latest version of Xcode):


property valtypesgens : {"Document", "Spreadsheet", "Presentation", "Image", "Sound", "Video", "Programming", "System", "Other"}

--...

on subremgen_(sender)
		log "worked"
	end subremgen_

--....

	on cffinishlaunching() --called from applicationWillFinishLaunching_
		subresetfldr() --ignore
		tell current application's class "NSBundle"
			tell its mainBundle()
				set valtypespreffile to (its pathForResource_ofType_("Custom File Types Pref", "txt")) as string --gets text file containing table data
				set valtypesgenspreffile to (its pathForResource_ofType_("Custom File Types Genres Pref", "txt")) as string --ignore
			end tell
		end tell
		set valtypespref to (read valtypespreffile using delimiter "%") as list --turns file contents into list with %
		set valtypesgenspref to (read valtypesgenspreffile using delimiter "%") as list --ignore
		if valtypesgenspref is {"$$$"} then set valtypesgenspref to {} --ignore
		--below groups threes of items into the rows as the column bindings' record structure
		repeat with valrep from 0 to ((count of valtypespref) / 3) - 1
			set valcusttypes to valcusttypes & {{valbwinfile:(item (valrep * 3 + 1) of valtypespref) as string, valbwingen:(item (valrep * 3 + 2) of valtypespref) as string, valbwinallo:(item (valrep * 3 + 3) of valtypespref) as boolean}}
		end repeat
		set my valbwindata to valdeftypes & valcusttypes --sets array binding to the default table property seen at top plus values just gotten from file
	-- this is the problem below, don't try understanding the top if you struggle
		repeat with valitem in (reverse of (valtypesgens & valtypesgenspref)) as list
			tell (valwintypeaddgenmen's insertItemWithTitle_action_keyEquivalent_atIndex_("Remove " & valitem, "subremgen:", "", 1))
				setKeyEquivalentModifierMask_(2^19)--NSAlternateKeyMask 1<<19
				setAlternate_(true)
			end tell
			valwintypeaddgen's insertItemWithTitle_atIndex_(valitem, 1)
		end repeat
	end cffinishlaunching

What happened? Did you get an error message? If so, post it.

I don’t know about the “tell” block you’re using – I never use that construction, so I’m not sure if it’s right. I haven’t seen people do it the way you’re doing it. Are the setKeyEquivalentModifierMask and setAlternate messages being sent to valItem or valwintypeaddgenmen?

Ric

It works fine, the tell line sends a message to the menu to create a menu item with the title and action, the value this message returns is an NSMenuItem, therefore the tell block sends the setKeyEquivalentModifierMask_ and setAlternate to the menu item, which work to successfully in repeat to make an Apple style option-menu. There is no error, it all works when the menu is made on launch but when I click the items no message is sent to the selector, no errors, just nothing.

Well, I’m sure that the syntax is correct for the selector – the one thing that is different from most methods that take a selector is that there is no target set. I think the target will be the first responder, whatever that is in your app, so maybe this script class is not the first responder? It’s hard to tell what might be going wrong without knowing more about the overall structure of your app.

Ric

https://files.me.com/imadrichard/tgbqma

You’re looking at ChooseFileController, some people say my hierarchical variable naming style is confusing, hope it’s not for you. Password is MacScripter. :smiley:

Is there a menu item at index 0 before you try to insert one at index 1?

Yes a disabled ‘genres…’ as a placeholder before selection, don’t worry, this is deliberate, probably easier to see this in my xib. Not that this would effect a message being sent, right? :slight_smile:

Where is the menu, valwintypeaddgenmen? I can’t find any reference to it in your nib

Ric

After Edit: Never mind, I found it.

I put this in the app delegate:

on subremgen_(sender)
		log "worked in the app delegate"
	end subremgen_

This was called when I clicked a menu item while holding down alt. So, the app delegate is the first responder. You can make your ChooseFileController script the target by adding setTarget_(me) under the tell statement.

Thanks, the menu instance variable is attached to the menu of the popup.

Thanks again, working perfectly after testing :smiley:

More random errors…

log "valwintext- " & valwintext's |string|()
log "valwintext- " & valwintext's performSelector_("string")
log "valwinent- " & valwinent's selectedColumn()
log "valwinent- " & valwinent's performSelector_("selectedColumn")

With a text view containing “abc” and the matrix with a selected column of 0:

the last log returns (NULL) if I don’t add text to the log

With a text view containing “abc” and the matrix with a selected column of 1:

return NSApplicationMain(argc, (const char **) argv);…EXC_BAD_ACCESS

is the error in the main.m although thats probably quite meaningless

What are you trying to accomplish with this line? Do you just want to log the selected column? If so, that’s not the way to do it, you just write:

log "valwinent- " & valwinent’s selectedColumn()

Ric

After Edit: I think the reason you don’t get the error when the selected column is zero, is because the return value of 0 from the selectedColumn method may be being interpreted as the NULL object – the return value of the performSelector method has to be an object, not a number, so if the return value is 1, this would give you the error. In any case, there’s no reason to use the performSelector method here.

This was just a piece of script I used to clarify the issue, it is necessary to save me bags of time. I understand your point about applescript coercions, therefore I will show you why I did the logs:

The whole point is to take a very large list of IBObjects with relevant selectors and put them through a try statement; but this try was supposed to catch unusual errors, I know as a fact that all the actions I have lined up to happen should work perfectly, therefore the try is not yet needed.

I don’t think it matters if performSelector returns an id or whatever because I am using a cocoa method to deal with it afterwards and I believe setObject_forKey_ requires an id for the first parameter.

When everything is commented out apart from the setObject I get this:

2011-07-13 18:01:17.183 Dialog Maker[2437:707] *** -[DisplayDialogController subgetprops:]: -[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: valwinent) (error -10000)

meaning the performSelector returns nil

--valpropscript is a large list of lists which are basically {key string, IBObject, selector in string form} e.g. {"valwintext", valwintext, "string"}, {"valwinent", valwinent, "selectedColumn"} are two of the items

set valproplist to NSMutableDictionary's dictionaryWithCapacity_(count valpropscript)

repeat with valprop in valpropscript
	--try
		log valproplist
		log valprop
		log 1
		log (item 2 of valprop)'s performSelector_(item 3 of valprop)
		log 2
		valproplist's setObject_forKey_((item 2 of valprop)'s performSelector_(item 3 of valprop), item 1 of valprop)
	--on error error_message
		--log error_message
		--valproplist's setObject_forKey_(error_message, item 1 of valprop)
	--end try
end

I think it does matter – the docs say that the selector you pass to performSelector has to return an object, whereas selectedColumn returns an NSUInteger. id refers to any object – that doesn’t include primitives like ints or floats and such. At least that’s my understanding.

The problem wasn’t with the log or any applescript coercion, because just saying “valwinent’s performSelector_(“selectedColumn”)” without any log still gives that error (in my test case anyway)

Ric

Thanks, OK, so what is my solution? I’m clueless, perhaps go back to the heart of the problem- taking every property and logging an appropriate value, although when I think about that the only thing would be to write millions of try statements. :frowning:

That’s correct but you can’t access ctypes with appleScriptObjC because an string isn’t coerced to an (char *) but to an NSString object. I’m only not sure about booleans because the YES and NO booleans in Objective-C are int types with value 1 and 0 and are not NSNumber or NSDecimal objects.

Well… I just made the replacement, if I didn’t know AS it would’ve been hell, take a look :slight_smile: hahahahahahaha

hopefully I don’t have to go manually coercing any of these into objects because the set object wants an object -.-

try
		valproplist's setObject_forKey_(valwintext's |string|(), "valwintext")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintext)
		end try
		try
		valproplist's setObject_forKey_(valwinent's selectedColumn(), "valwinent")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinent)
		end try
		try
		valproplist's setObject_forKey_(valwinentdef's stringValue(), "valwinentdef")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinentdef)
		end try
		try
		valproplist's setObject_forKey_(valwinentsec's selectedColumn(), "valwinentsec")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinentsec)
		end try
		try
		valproplist's setObject_forKey_(valwinbut's selectedColumn(), "valwinbut")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbut)
		end try
		try
		valproplist's setObject_forKey_(valwinbut1's stringValue(), "valwinbut1")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbut1)
		end try
		try
		valproplist's setObject_forKey_(valwinbut2's stringValue(), "valwinbut2")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbut2)
		end try
		try
		valproplist's setObject_forKey_(valwinbut3's stringValue(), "valwinbut3")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbut3)
		end try
		try
		valproplist's setObject_forKey_(valwinbutdef's indexOfSelectedItem(), "valwinbutdefIndex")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbutdefIndex)
		end try
		try
		valproplist's setObject_forKey_(valwinbutdef's itemTitles(), "valwinbutdefTitles")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbutdefTitles)
		end try
		try
		valproplist's setObject_forKey_(valwinbutcal's indexOfSelectedItem(), "valwinbutcalIndex")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbutcalIndex)
		end try
		try
		valproplist's setObject_forKey_(valwinbutcal's itemTitles(), "valwinbutcalTitles")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinbutcalTitles)
		end try
		try
		valproplist's setObject_forKey_(valwintit's selectedRow(), "valwintit")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintit)
		end try
		try
		valproplist's setObject_forKey_(valwintitnam's stringValue(), "valwintitnam")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintitnam)
		end try
		try
		valproplist's setObject_forKey_(valwinicon's titleOfSelectedItem(), "valwinicon")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinicon)
		end try
		try
		valproplist's setObject_forKey_(valwiniconpic's image()'s name(), "valwiniconpic")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwiniconpic)
		end try
		try
		valproplist's setObject_forKey_(valwinicontext's isHidden(), "valwinicontext")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinicontext)
		end try
		try
		valproplist's setObject_forKey_(valwiniconspn's isHidden(), "valwiniconspn")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwiniconspn)
		end try
		try
		valproplist's setObject_forKey_(valwintmout's selectedColumn(), "valwintmout")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintmout)
		end try
		try
		valproplist's setObject_forKey_(valwintmoutmin's stringValue(), "valwintmoutmin")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintmoutmin)
		end try
		try
		valproplist's setObject_forKey_(valwintmoutsec's stringValue(), "valwintmoutsec")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintmoutsec)
		end try
		try
		valproplist's setObject_forKey_(valwintmoutminstp's intValue(), "valwintmoutminstp")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintmoutminstp)
		end try
		try
		valproplist's setObject_forKey_(valwintmoutsecstp's intValue(), "valwintmoutsecstp")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwintmoutsecstp)
		end try
		try
		valproplist's setObject_forKey_(valwinstt's selectedRow(), "valwinstt")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinstt)
		end try
		try
		valproplist's setObject_forKey_(valwinsttpopup's titleOfSelectedItem(), "valwinsttpopup")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttpopup)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbut's state(), "valwinsttbut")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbut)
		end try
		try
		valproplist's setObject_forKey_(valwinstttext's state(), "valwinstttext")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinstttext)
		end try
		try
		valproplist's setObject_forKey_(valwinstttmout's state(), "valwinstttmout")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinstttmout)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifbutokcan's isHidden(), "valwinsttifbutokcan")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifbutokcan)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifbut1's isHidden(), "valwinsttifbut1")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifbut1)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifbut2's isHidden(), "valwinsttifbut2")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifbut2)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifbut3's isHidden(), "valwinsttifbut3")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifbut3)
		end try
		try
		valproplist's setObject_forKey_(valwinsttiftext's isHidden(), "valwinsttiftext")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttiftext)
		end try
		try
		valproplist's setObject_forKey_(valwinsttiftmouttrue's isHidden(), "valwinsttiftmouttrue")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttiftmouttrue)
		end try
		try
		valproplist's setObject_forKey_(valwinsttiftmoutfalse's isHidden(), "valwinsttiftmoutfalse")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttiftmoutfalse)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifvar's stringValue(), "valwinsttifvar")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifvar)
		end try
		try
		valproplist's setObject_forKey_(valwinsttifvarclr's isHidden(), "valwinsttifvarclr")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttifvarclr)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext1's stringValue(), "valwinsttbuttext1")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext1)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext2's stringValue(), "valwinsttbuttext2")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext2)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext3's stringValue(), "valwinsttbuttext3")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext3)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext1clr's isHidden(), "valwinsttbuttext1clr")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext1clr)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext2clr's isHidden(), "valwinsttbuttext2clr")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext2clr)
		end try
		try
		valproplist's setObject_forKey_(valwinsttbuttext3clr's isHidden(), "valwinsttbuttext3clr")
		on error error_message
		valproplist's setObject_forKey_(error_message, valwinsttbuttext3clr)
		end try
		return valproplist

Edit: error:

2011-07-13 20:44:08.739 Dialog Maker[2797:707] -[NSImageView copyWithZone:]: unrecognized selector sent to instance 0x4008dff80
2011-07-13 20:44:08.770 Dialog Maker[2797:707] *** -[DisplayDialogController subgetprops:]: -[NSImageView copyWithZone:]: unrecognized selector sent to instance 0x4008dff80 (error -10000)

it even escapes the try, it refers specifically to this:

try
	valproplist's setObject_forKey_(valwiniconpic's image()'s |name|(), "valwiniconpic")
on error error_message
	valproplist's setObject_forKey_(error_message, valwiniconpic)
end try

It’s hard to say what’s wrong with that without more info – what is valwiniconpic?

Ric