Re: Fun and games with Applescript "Standard Suite" in Cocoa app
Re: Fun and games with Applescript "Standard Suite" in Cocoa app
- Subject: Re: Fun and games with Applescript "Standard Suite" in Cocoa app
- From: "Neal A. Crocker" <email@hidden>
- Date: Thu, 23 Aug 2001 14:48:40 -0700
Brian, thanks for the extensive reply. I only have a short time to
reply back (lunch break, you know?) so I'll respond in more detail
(relatively speaking) later, but the short explanation for my
questions is that I want to create a cocoa app. that acts as a shell
for an Applescript script (i.e. I want to "embed" a script in an
cocoa app., so that the script handles the appleevents that are sent
to the "application" script object of the app.). Ultimately, I'd
like to develop a script shell that offers Applescripters (such as
myself) a more powerful way of making Applescript applications
(sometimes refered to as applets and droplets) than is offered by the
default option available through Script Editor. In particular, I
want to develop a shell that offers Aqua user inteface capabilities
to the scripter. The available user interface options for
Applescript don't quite meet my needs (which, I imagine, are not that
unique). For instance, the "display dialog" and other interface
capabilities available in vanilla Applescript are very limited.
Facespan and similar Applescript application development evironments
seem nice, but I don't want to pay for it if I can develop what I
need for myself (and offer as freeware to others who are brave enough
to try out the product of my freshman attempt at making something
useful for the mac). The various scripting additions available to
add interface capababilities to Applescript don't quite meet my
vision (and, as the saying goes, "if you don't like the way its being
done, do it yourself"). The freeware Applescript application
development environment "Smile" comes the closest to what I envision,
but, again, it is still far enough away that I felt compelled do some
developing of my own.
Let me adress the purpose behind some of the other quesions I raised.
Some of the things I asked about were: (1) adding and, in particular,
removing properties from the dictionary description of a Standard
Suite object and (2) adding the run event to the Standard Suite.
Both of these are motivated by the fact that Applescript
applications, as created from scripts using Script Editor, are
implicitly scriptable because any event sent to them will be passed
on to their embedded Applescripts, yet they don't show Applescript
dictionaries. I want to give the Applescripter who uses my shell for
his/her script the ability to create and control the contents of the
resulting Applescript application's dictionary. Most Applescript
applications, in my experience, handle the run command, so I'd like
the run command to show up in the dictionary if desired by the
Applescripter. Thus I, as the shell developer, need to figure out how
to make this capability available. Also, in my experience, most
Applescript applications don't have windows, so if my script shell
shows the Standard Suite (which, again, would be at the discretion of
the Applescripter), it should be able to show a modified version of
the application object in its dicitionary which doesn't have a
"window" element class. Ultimately, as the developer of the shell,
I'd like to have complete control, within the scope of Cocoa and
Project Builder, of whether the Standard Suite is part of the
applescript dictionary and of what it contains when it is, so that I
can give the Applescripter the control he/she needs to present an
appropriately tailored Standard Suite for an Applescript application
built using my shell. While, I know (or can figure out), of course,
how to give the scripter control of application specific suites, I
haven't been able to figure out how to control (and pass on control
of) the contents of the Standard Suite. I feel that this control is
necessary because I have a hard time imagining that Apple's standard
for developing scriptable applications is, or is going to be, that a
given object, such as the application object, should be defined in
multiple suites because I know that application dictionaries which do
this, such as that of Sketch, tend to baffle me as an Applescripter.
I therefore want any Applecripter that uses my shell for serious
application devopment to not be forced to do such things in an effort
to, for instance, customize the definition of the application object
in their application dictionary. (For that matter, I, as a would-be
devoloper of scriptable Cocoa apps., am glad to get the Standard
Suite "for free", but I would ultimately like to find that it is not
forced on me, or, at least, not forced on me without recourse to
adjustment.)
By the way, what method should an NSApplicationg delegate implement
to handle this run applevent whenever it is sent to the app. on
startup and after it is already started.?
Thanks,
Neal.
On Thursday, August 23, 2001, at 06:04 AM, Neal Crocker wrote:
I've been trying to learn how to implement scripting support in Cocoa
and I've come up with a number of questions that I can't find answers
to in the Cocoa, Carbon and Interapp. Communication documentation. I
was hoping I could find someone (or many someones) with answers to
these question here. For instance, how do I go about modifying or
orverriding the "Standard Suite" in my application?
To do this, you should create your own script suite, and for any
class or command you want to override, just insert a definition for
that class or command in your suite and make sure it has the same
AppleEventCode specified, and it would probably be smart to specify
the same name in the corresponding .scriptTerminology file, as to
avoid confusing both Applescript and your scripters.
For an example, take a look at Sketch.app or TextEdit.app. Each of
them specifies their own "subclass" of NSApplication (not to say
that NSApplication was actually subclassed in code, but rather had
functionality added to it via categories/delegate methods) and
defines additional properties/elements accessible via the main
application object. The subclass has the same 'capp' event code
specified, so it replaces the default definition given by the
frameworks, but since it inherits from the NSApplication definite
given in the frameworks, all of its default properties are preserved
as well.
When I created a
scriptable version of the canonical "Nothing" Cocoa application in
Project Builder (by creating a Cocoa application and doing nothing
more than adding the application setting NSAppleScriptEnable with
value YES), it had a scripting dictionary which included the Standard
Suite (as I expected from reading the Cocoa documentation). The
Standard Suite doesn't appear to have a "run" command. I'd like to
put the strangely absent "run" command back into the Standard Suite
where, as far as I know, it belongs.
Well, there isn't a run command specified in the script dictionary,
but it appears to work just fine. Try running 'tell application
"TextEdit" to run', and it launches it as expected.
I'd also like to modify the Standard Suite so that I
could, for instance, add and eliminate properties from the
"application" object, or one of the other defined objects.
Adding stuff is easy, but why would you want to eliminate properties
from the existing classes? I just can't think of any reason to want
to do this, and besides, it would be pretty difficult to do. You
could probably work some hack that subclasses NSScriptSuiteRegistry
and filters out the definitions you don't want there, but I sure
wouldn't want to try this.
I've
noticed that some other scriptable cocoa apps (e.g. Sketch) define
objects in their script suites that are already defined in their
Standard Suite, but define them with different properties and/or
element classes. Not only does this seem awkward, it bewilders me.
If an Applescript is compiled against such a dictionary, how are such
conflicts resolved?.
It is a little bit strange to have multiple definitions for a single
class in different suites. The overriding behavior is explained
somewhat in the docs of the classDescriptionWithAppleEventCode:
method of NSScriptSuiteRegistry. Basically, when you have multiple
classes that claim the same event code, the one that inherits the
deepest wins.
On a related note, how do I implement some behaviour for Applescript
commands such as "quit" or "run" (not just for the intial app.
startup, but for every time app. receives the "run" appleevent) for
the application object. The documentation seem clear on how to
implement behavior for my app. model classes, but not for the
application object.
Well, for most instances, you should be able to just put in your
code in the appropriate methods of your application's delegate. For
instance, to run some code on quitting, you'd just override
applicationWillTerminate: in your delegate, and this would be called
when a 'quit' Apple Event was sent to your program and cause the app
to quit.
If you want to specifically override what happens when a specific
command is sent to your app, you do something very similar to what's
done for overriding classes, instead this time, you override the
appropriate command in the class definition. For instance, to
override the behavior of the close command when sent to an object of
yours, you'd add an entry under the SupportedCommands key of the
script suite and specifiy a selector that you which to be invoked on
your object when that script command is sent.
This is particularly important to do in many cases with commands
such as copy and move, since the default implementation is often not
sufficient. Now, since the run command isn't defined in the script
suite, I guess there's no way to override it aside from installing
your own Apple Event handler. But again, I really really can't
think of why you'd want or need to do this. Do you have something
specific in mind?
--
Brian Webster
email@hidden
http://www.owlnet.rice.edu/~bwebster