Basic Questions Part II

  1. Why do this handler work

on applicationDidFinishLaunching_(aNotification)
display alert “Hallo” – OK
end applicationDidFinishLaunching_

but this one not ?

on applicationWillFinishLaunching_(aNotification)
display alert “Hallo” – No answer
end applicationWillFinishLaunching_

  1. Why do this handler work

on applicationShouldTerminateAfterLastWindowClosed_(NSApp)
return true
end applicationShouldTerminateAfterLastWindowClosed_

but these handlers not ?
(The app should open without a start window)

on applicationOpenUntitledFile_(NSApp)
return false
end applicationOpenUntitledFile_

on applicationShouldOpenUntitledFile_(NSApp)
return false
end applicationShouldOpenUntitledFile_

Heiner

They both work here, although if I put both in the same script, only the second dialog appears. But if you change the dialog to a “log” call, you can see that both handlers then get called – at least, they do here.

Shane sorry for my doggedness, but nearly all I know of ASS is gone with upcoming of ASOC.

To my questions:

I made two new innocent projects, one as a non-document-based app and one as a document-based app.

In the first one the WillFinishLaunching and the DidFinishLaunching works directly.

In the second one first I bound - due to Craigs hint - the Application icon to the FilesOwner icon for a delegate connection.
Only the DidFinish-handler works, the other one said nothing. (Even not a log message)
But I’m able to live with that; it should only relieve the awakeFromNib-handler.

The second question I asked is more importend for me. The app should open without a window. The user can choose either he wants to start a new document or he wants to open an existing file. (To click off an empty start window is not very elegantly)

I thought the applicationShouldOpenUntitledFile_(NSApp)-handler would be the right one.
(Bindings?, bindings? I think I have nearly bound all what has no legs to run)
Any idea

Heiner

No need to apologise!

I haven’t done anything with document-based apps, but my suggestion would be this: create a new AS class (File → New), instantiate it in MainMenu.xib (that is, drag a blue NSObject cube into the xib window and change it’s class to your new class), and make it a delegate of the application (control-click on the App icon, and drag from delegate to the blue cube). Put your application-related handlers in this new class, and put you document related stuff in MyDocument.applescript. The two can talk to each other if need be, unlike in ASS.

Your problem, I think, is that you’re trying to make MyDocument.applescript the app delegate, but I believe the app delegate has to be a single instance, whereas a separate MyDocument instance is used for each document, and the instances (as opposed to the class) are only created at run time.

The documents suggest you can subclass NSDocumentController and use that as the app delegate, but unless you plan to subclass it for some other reason, I’d stick with the above.

Shane
thanks for the moment; I need a little bit of time now.

Heiner

Well I’m there again.

I did that due to your post:

  1. create a new AS class, name it ‘MyApplication’
  2. in MainMenu.xib add a blue cube (NSObject)
  3. “…change it’s class to your new class” – don’t know how
  4. bind from App icon to blue cube- connect delegate
  5. put some app rel. handlers into new class [on init(), on windowControllerDidLoadNib_(aController), on windowNibName()]

Heiner

With the cube selected, show the Identity inspector and type where it says Class.

My new class was already known in the Identity inspector, I selected it.

But only the main menu appeares after compiling, no window.
And the the handler

on applicationDidFinishLaunching_(aNotification)
log “Hallo”
display alert “Hallo”
end applicationDidFinishLaunching_

shows no reaction.

However the system-menus [About, Open, Save, etc.] pop up and show there panels.

Heiner

If this was in the MyDocument xib, humor me and undo the connection.

Shane,
it looks good, it looks damned good!

First I disconnected the old delegate connection as you wrote.

But then I have to admid a heavy mistake by myself: I created a new additional document class instead of a class of NSObject. But that’s clean now and the document related handlers are working properly in the new subclass.

I’m very grateful to you.

Heiner

[For information to others: the basic handlers as ‘on init(), on windowControllerDidLoadNib_(aController), on windowNibName()’ must stay in MyDocument.applesript and not in the new subclass as I wrote in # 6]

Phew! Good news!

Oh God!

I think I got my hopes too soon.

The two classes don’t talk to each other. The new subclass understand in the app-related handler true or false only, but handler calls to MyDocument not.
On the other hand the class MyDocument don’t understand the app-related handler any longer.
It’s anguish.

Heiner

PS:
Shaine
I don’t take up all of your time in this problem anymore.

The one task to start the app without a window is with this solution solved.
For the other tasks (registerPrefs, readPrefs, writePrefs) I take the awakeFromNib handler or I call this handler inside the particular handler who changed the properties immediately.

Thanks again

Heiner

They do if you ask them nicely.

Suppose you have a handler in your app delegateL

	on doStuff_(x)
		display dialog (x as text)
	end doStuff_

You can call that from MyDocument like this:

Going the other is trickier, but it can be done.

So no more anguish…

That’s good to hear,

but this method seems to be limited for a handful parameters.

What’s about - for example - managing user defaults stuff or initialisiation of a large bundle of properties in

on applicationDidFinishLaunching_(aNotification)
???
end applicationDidFinishLaunching

applicationDidFinishLaunching only works from your app’s delegate class. There’s a few ways to do what you want. They all require creating an instance of your MyDocument class (to use Shane’s example class names) in your app delegate.

Outside of calling the app delegate class from another class (Shane’s example: current application’s NSApp’s delegate()'s… ) the most straightforward way to communicate between classes is to do the following:

Create a property in your AppDelegate class

Create an instance of your MyDocument class in your interface builder NIB, yet another blue cube; I do this in Interface Builder by going to the Library (cmd-shift-L) , classes tab and searching for the name of my class, then drag it onto your NIB. Then, select your AppDelegate class’s blue cube, hold control-key down and click then drag from your AppDelegate blue cube to your MyDocument blue cube. A context-menu should pop-up and you should see the property you created, DocClass; select that.

Now your AppDelegate class can talk to your MyDocument class because its property DocClass is pointing at an instance of your MyDocument class.

If your MyDocument class has a method:

then, in your AppDelegate’s on applicationDidFinishLaunching:

Should let you manage user defaults and initialize whatever you need to when your application launches. It’s also an example of how you can run any method in one ASOC class, from another.

That won’t work in an document-based app – MyDocument is in its own nib, and is instantiated every time a new document is created.

I’m not sure what the problem is. Are you saying you want to set a lot of properties at startup, and access these from every document?

What a pity that elspub’s method don’t work. It would solve a lot of problems.
Many thanks to elspub!!

Shane wrote:

Sorry I do not mean ‘properties’ (they are on top of the script) but all the things which are going in the amakeFromNib-handler too. It’s just for distrbution and I don’t want to ‘put all eggs in one basket’.

The other thing is a current task I’m working.

I made my own about-panel and it should popup at start up for a few seconds. I try to transform the following ASS handler:


on will finish launching theObject
	set myVersion to version of application "MyApplication" 
	set contents of text field "version" of window "Startup" to myVersion
	show window "startup"
	delay 2.5
	hide window "startup"
	--registerPreferences() -- I put it into awakeFromNib
	--readPreferences() -- I put it into awakeFromNib
end will finish launching

How do I get the Informations (version, startupWindow, sender) into the DidFinishLaunching-handler?


on applicationDidFinishLaunching_(aNotification)
		startupWindow's makeKeyAndOrderFront_(sender)
		delay 2.5
		startupWindow's orderOut_(sender)
	end applicationDidFinishLaunching_

Heiner

You get the version from the info.plist using NSBudle, something like this:

set theVersion to current application's NSBundle's mainBundle()'s objectForInfoDictionaryKey_("CFBundleVersion")

For startupWindow, you make a property and connect it to the window in Interface Builder. And sender in this case can be anything, as it’s not going to be used.

And you might want to get rid of “delay” – it tends to consume 100% of processor power in ASObjC projects. You can try something like this:

current application's NSThread's sleepUntilDate_( current application's NSDate's |date|()'s dateByAddingTimeInterval_(2.5))