rb-appscript 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +243 -0
- data/LICENSE +1 -0
- data/README +42 -0
- data/TODO +31 -0
- data/doc/aem-manual/01_introduction.html +48 -0
- data/doc/aem-manual/02_apioverview.html +89 -0
- data/doc/aem-manual/03_packingandunpackingdata.html +98 -0
- data/doc/aem-manual/04_references.html +401 -0
- data/doc/aem-manual/05_targettingapplications.html +133 -0
- data/doc/aem-manual/06_buildingandsendingevents.html +175 -0
- data/doc/aem-manual/07_findapp.html +54 -0
- data/doc/aem-manual/08_examples.html +85 -0
- data/doc/aem-manual/09_notes.html +41 -0
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/full.css +21 -0
- data/doc/aem-manual/index.html +43 -0
- data/doc/appscript-manual/01_introduction.html +82 -0
- data/doc/appscript-manual/02_aboutappscripting.html +244 -0
- data/doc/appscript-manual/03_quicktutorial.html +154 -0
- data/doc/appscript-manual/04_gettinghelp.html +101 -0
- data/doc/appscript-manual/05_keywordconversion.html +91 -0
- data/doc/appscript-manual/06_classesandenums.html +174 -0
- data/doc/appscript-manual/07_applicationobjects.html +181 -0
- data/doc/appscript-manual/08_realvsgenericreferences.html +86 -0
- data/doc/appscript-manual/09_referenceforms.html +232 -0
- data/doc/appscript-manual/10_referenceexamples.html +142 -0
- data/doc/appscript-manual/11_applicationcommands.html +204 -0
- data/doc/appscript-manual/12_commandexamples.html +129 -0
- data/doc/appscript-manual/13_performanceissues.html +115 -0
- data/doc/appscript-manual/14_problemapps.html +193 -0
- data/doc/appscript-manual/15_notes.html +84 -0
- data/doc/appscript-manual/application_architecture.gif +0 -0
- data/doc/appscript-manual/application_architecture2.gif +0 -0
- data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
- data/doc/appscript-manual/full.css +21 -0
- data/doc/appscript-manual/index.html +49 -0
- data/doc/appscript-manual/relationships_example.gif +0 -0
- data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
- data/doc/index.html +30 -0
- data/doc/mactypes-manual/index.html +216 -0
- data/doc/osax-manual/index.html +169 -0
- data/extconf.rb +54 -0
- data/misc/adobeunittypes.rb +14 -0
- data/misc/dump.rb +72 -0
- data/rb-appscript.gemspec +20 -0
- data/sample/AB_list_people_with_emails.rb +8 -0
- data/sample/Create_daily_iCal_todos.rb +72 -0
- data/sample/Hello_world.rb +9 -0
- data/sample/List_iTunes_playlist_names.rb +7 -0
- data/sample/Make_Mail_message.rb +29 -0
- data/sample/Open_file_in_TextEdit.rb +9 -0
- data/sample/Organize_Mail_messages.rb +57 -0
- data/sample/Print_folder_tree.rb +12 -0
- data/sample/Select_all_HTML_files.rb +8 -0
- data/sample/Set_iChat_status.rb +20 -0
- data/sample/Simple_Finder_GUI_Scripting.rb +14 -0
- data/sample/Stagger_Finder_windows.rb +21 -0
- data/sample/TextEdit_demo.rb +126 -0
- data/sample/iTunes_top40_to_html.rb +64 -0
- data/src/lib/_aem/aemreference.rb +1006 -0
- data/src/lib/_aem/codecs.rb +617 -0
- data/src/lib/_aem/connect.rb +100 -0
- data/src/lib/_aem/findapp.rb +83 -0
- data/src/lib/_aem/mactypes.rb +228 -0
- data/src/lib/_aem/send.rb +257 -0
- data/src/lib/_aem/typewrappers.rb +57 -0
- data/src/lib/_appscript/defaultterminology.rb +245 -0
- data/src/lib/_appscript/referencerenderer.rb +132 -0
- data/src/lib/_appscript/reservedkeywords.rb +107 -0
- data/src/lib/_appscript/terminology.rb +314 -0
- data/src/lib/aem.rb +216 -0
- data/src/lib/appscript.rb +830 -0
- data/src/lib/kae.rb +1484 -0
- data/src/lib/osax.rb +171 -0
- data/src/rbae.c +766 -0
- data/test/README +1 -0
- data/test/test_aemreference.rb +112 -0
- data/test/test_appscriptreference.rb +102 -0
- data/test/test_codecs.rb +159 -0
- data/test/test_findapp.rb +24 -0
- data/test/test_mactypes.rb +67 -0
- data/test/testall.sh +9 -0
- metadata +143 -0
@@ -0,0 +1,401 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
|
5
|
+
<title>aem | 4. References</title>
|
6
|
+
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<style type="text/css" media="all"><!--@import url(full.css);--></style>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<h1>4. References</h1>
|
14
|
+
|
15
|
+
<!-- top navigation -->
|
16
|
+
<div class="navbar">
|
17
|
+
<a href="03_packingandunpackingdata.html">Previous</a> | <a href="index.html">Up</a> | <a href="05_targettingapplications.html">Next</a>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<!-- content -->
|
21
|
+
<div id="content">
|
22
|
+
|
23
|
+
|
24
|
+
<h2>About references</h2>
|
25
|
+
|
26
|
+
<p>An Apple Event Object Model query (a.k.a. "reference") essentially consists of a linked list made up of one or more Apple event descriptors (AEDescs) of, for the most part, <code>typeObjectSpecifier</code>. Object specifiers are used to identify properties and elements in the application's AEOM. Each object specifer contains four fields:</p>
|
27
|
+
|
28
|
+
<dl>
|
29
|
+
<dt>want</dt>
|
30
|
+
<dd>four-char-code indicating desired element(s)'s class code (e.g. 'docu' = document), or 'prop' if it's a property specifier</dd>
|
31
|
+
|
32
|
+
<dt>from</dt>
|
33
|
+
<dd>an object specifer identifying container object(s)</dd>
|
34
|
+
|
35
|
+
<dt>form</dt>
|
36
|
+
<dd>four-char-code indicating how the element(s) should be selected (by index ['indx'], name ['name'], etc.), or 'prop' if it's a property specifier</dd>
|
37
|
+
|
38
|
+
<dt>seld</dt>
|
39
|
+
<dd>selector data (e.g. in a by-name specifier, this would be a string)</dd>
|
40
|
+
</dl>
|
41
|
+
|
42
|
+
<p>The Apple Event Manager (and, in turn, the ae extension) provides several ways to construct object specifiers and assemble them into a complete reference, but these are all rather verbose and low-level. Aem hides all these details behind an object-oriented wrapper that uses chained property and method calls to gather the data needed to create object specifiers and assemble them into linked lists.</p>
|
43
|
+
|
44
|
+
<p>For example, consider the reference <code>text of document 1</code>. The code for constructing this reference using a relatively low-level bridge, in this case RubyAEOSA, would be:</p>
|
45
|
+
|
46
|
+
<pre><code>ref = OSX::AEDesc.null
|
47
|
+
|
48
|
+
ref = OSX::AEDesc.record({
|
49
|
+
'want' => OSX::AEDesc.new('type', 'docu'),
|
50
|
+
'from' => ref,
|
51
|
+
'form' => OSX::AEDesc.new('enum', 'indx'),
|
52
|
+
'seld' => 1,
|
53
|
+
}).coerce('obj ')
|
54
|
+
|
55
|
+
ref = OSX::AEDesc.record({
|
56
|
+
'want' => OSX::AEDesc.new('type', 'prop'),
|
57
|
+
'from' => ref,
|
58
|
+
'form' => OSX::AEDesc.new('enum', 'prop'),
|
59
|
+
'seld' => OSX::AEDesc.new('type', 'ctxt'),
|
60
|
+
}).coerce('obj ')
|
61
|
+
|
62
|
+
p ref
|
63
|
+
#<AEDesc:0x57594 type='obj '></code></pre>
|
64
|
+
|
65
|
+
<p>(The ae extension is even lower-level and more verbose.)</p>
|
66
|
+
|
67
|
+
<p>This code works by creating each AEDesc of <code>typeAERecord</code> in turn, populating it, then coercing it to <code>typeObjectSpecifier</code>. Each AEDesc is nested within the next to form a linked list of object specifier records; the last (innermost) descriptor in the finished list indicates the reference's root object in the AEOM (in this case, the <code>application</code> object, which is represented by a null descriptor).</p>
|
68
|
+
|
69
|
+
<p>Now, compare the above with the aem equivalent:</p>
|
70
|
+
|
71
|
+
<pre><code>AEM.app.elements('docu').by_index(1).property('ctxt')</code></pre>
|
72
|
+
|
73
|
+
<p>As you can see, aem still uses low-level four-character codes to identify the <code>text</code> property and <code>document</code> class, but is otherwise a high-level object-oriented API. Once again, each reference begins with a root object, in this case <code>app</code>. New aem specifiers are constructed by method calls; each call returning a new specifier object whose own methods can be called, and so on. This allows clients to build up a chain of aem specifier objects that aem can later pack into AEDescs for sending to applications.</p>
|
74
|
+
|
75
|
+
<p>One more thing to notice: in aem, specifying a class of elements and indicating which of those elements should be selected are performed by separate method calls, although the information provided will eventually be packed into a single AEDesc of <code>typeObjectSpecifier</code>. This two-step approach makes it easier to integrate aem with the higher-level appscript bridge, which also uses two calls to construct element specifiers (one to specify the element class, e.g. <code>document</code>, and another to specify the selection, e.g. <code>[1]</code>).</p>
|
76
|
+
|
77
|
+
<p>Note that <code>AEM.app.elements('docu')</code> is itself a valid reference, identifying <em>all</em> the document elements of the application class. You do not have to call an explicit <code>all</code> selector (indeed, none is provided) as aem automatically handles the details for you. Aem even allows for some convenient shorthand, e.g. writing:</p>
|
78
|
+
|
79
|
+
<pre><code>AEM.app.elements('docu').by_filter(...).first</code></pre>
|
80
|
+
|
81
|
+
<p>is equivalent to writing:</p>
|
82
|
+
|
83
|
+
<pre><code>AEM.app.elements('docu').by_filter(...).elements('docu').first</code></pre>
|
84
|
+
|
85
|
+
<p>This allows clients to specify the first document that matches the given condition without having to specify the element class a second time. In AppleScript, the equivalent to this is:</p>
|
86
|
+
|
87
|
+
<pre><code>first document whose ...</code></pre>
|
88
|
+
|
89
|
+
<p>which is short for:</p>
|
90
|
+
|
91
|
+
<pre><code>first document of (documents whose ...)</code></pre>
|
92
|
+
|
93
|
+
<p>(Again, this additional behaviour primarily exists to serve the syntactically sugared appscript layer.)</p>
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
<h2>Reference forms</h2>
|
98
|
+
|
99
|
+
<p>Aem defines a number of classes representing each of the AEOM reference forms. There are eight AEOM reference forms:</p>
|
100
|
+
|
101
|
+
<ul>
|
102
|
+
<li>insertion location</li>
|
103
|
+
<li>property</li>
|
104
|
+
<li>element by absolute position (index or ordinal)</li>
|
105
|
+
<li>element by name</li>
|
106
|
+
<li>element by id</li>
|
107
|
+
<li>element by relative position</li>
|
108
|
+
<li>elements by range</li>
|
109
|
+
<li>elements by test</li>
|
110
|
+
</ul>
|
111
|
+
|
112
|
+
<p>(Actually, there's nine forms if you count the 'user property' reference form, although this is only used by OSA applets to identify script properties. Aem supports this extra form more for sake of completeness than usefulness.)</p>
|
113
|
+
|
114
|
+
<p>Each of these reference forms is represented by a different aem specifier class, apart from the absolute position form which is represented by three different classes according to the kind of selector used: a numerical index (e.g. <code>1</code>, <code>-3</code>), a named ordinal identifying a single element (<code>first</code>, <code>middle</code>, <code>last</code>, <code>any</code>), or a named ordinal identifying all elements (<code>all</code>).</p>
|
115
|
+
|
116
|
+
<p>The following diagram shows the aem reference class hierarchy (slightly simplified for legibility); concrete classes are shown in bold:</p>
|
117
|
+
|
118
|
+
<p><img src="aemreferenceinheritance.gif" title="aem reference class hierarchy" />
|
119
|
+
|
120
|
+
<p>Note that the user shouldn't instantiate these classes directly; instead, aem will instantiate them as appropriate when the client calls the properties and methods of one of the three root objects - <code>app</code>, <code>con</code>, <code>its</code> - of of other aem reference objects.</p>
|
121
|
+
|
122
|
+
<p>In fact, it really isn't necessary to remember the reference class hierarchy at all, only to know which concrete classes implement which methods. All user-accessible properties and methods are defined by just four superclasses:</p>
|
123
|
+
|
124
|
+
<dl>
|
125
|
+
<dt><code>BASE</code></dt>
|
126
|
+
<dd>Defines comparison and hashing methods.</dd>
|
127
|
+
|
128
|
+
<dt><code>PositionSpecifier</code></dt>
|
129
|
+
<dd>Defines methods for identifying properties and all elements, insertion locations, elements by relative position. Also defines comparison and logical test methods for use in constructing its-based references.</dd>
|
130
|
+
|
131
|
+
<dt><code>MultipleElements</code></dt>
|
132
|
+
<dd>Defines methods for identifying specific elements of a multi-element reference.</dd>
|
133
|
+
|
134
|
+
<dt><code>Test</code></dt>
|
135
|
+
<dd>Defines logical test methods for use in constructing its-based references.</dd>
|
136
|
+
</dl>
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
<h2>Base classes</h2>
|
141
|
+
|
142
|
+
<h3>Basic methods</h3>
|
143
|
+
|
144
|
+
<pre><code>BASE -- Base class for all reference form and test clause classes.
|
145
|
+
hash -- aem references can be used as dictionary keys
|
146
|
+
|
147
|
+
==(value) -- aem references can be compared for equality</code></pre>
|
148
|
+
|
149
|
+
|
150
|
+
<h3>Methods for all position specifiers</h3>
|
151
|
+
|
152
|
+
<pre><code>PositionSpecifier < Specifier -- base class for all property and element
|
153
|
+
reference forms (i.e. all forms except insertion location)
|
154
|
+
|
155
|
+
Methods:
|
156
|
+
|
157
|
+
start
|
158
|
+
Result : InsertionSpecifier
|
159
|
+
|
160
|
+
end
|
161
|
+
Result : InsertionSpecifier
|
162
|
+
|
163
|
+
before
|
164
|
+
Result : InsertionSpecifier
|
165
|
+
|
166
|
+
after
|
167
|
+
Result : InsertionSpecifier
|
168
|
+
|
169
|
+
property(property_code)
|
170
|
+
property_code : str -- four-char code
|
171
|
+
Result : Property
|
172
|
+
|
173
|
+
user_property(name)
|
174
|
+
name : str
|
175
|
+
Result : UserProperty
|
176
|
+
|
177
|
+
elements(class_code)
|
178
|
+
class_code : str -- four-char code
|
179
|
+
Result : AllElements
|
180
|
+
|
181
|
+
previous(class_code)
|
182
|
+
class_code : str -- four-char code
|
183
|
+
Result : Element
|
184
|
+
|
185
|
+
next(class_code)
|
186
|
+
class_code : str -- four-char code
|
187
|
+
Result : Element
|
188
|
+
|
189
|
+
-- Note: following methods are for use on
|
190
|
+
its-based references only
|
191
|
+
|
192
|
+
gt(val) -- self is greater than value
|
193
|
+
val : anything
|
194
|
+
Result : Test
|
195
|
+
|
196
|
+
ge(val) -- self is greater than or equal to value
|
197
|
+
val : anything
|
198
|
+
Result : Test
|
199
|
+
|
200
|
+
eq(val) -- self equals value
|
201
|
+
val : anything
|
202
|
+
Result : Test
|
203
|
+
|
204
|
+
ne(val) -- self does not equal value
|
205
|
+
val : anything
|
206
|
+
Result : Test
|
207
|
+
|
208
|
+
lt(val) -- self is less than value
|
209
|
+
val : anything
|
210
|
+
Result : Test
|
211
|
+
|
212
|
+
le(val) -- self is less than or equal to value
|
213
|
+
val : anything
|
214
|
+
Result : Test
|
215
|
+
|
216
|
+
starts_with(val) -- self starts with value
|
217
|
+
val : anything
|
218
|
+
Result : Test
|
219
|
+
|
220
|
+
ends_with(val) -- self ends with value
|
221
|
+
val : anything
|
222
|
+
Result : Test
|
223
|
+
|
224
|
+
contains(val) -- self contains value
|
225
|
+
val : anything
|
226
|
+
Result : Test
|
227
|
+
|
228
|
+
is_in(val) -- self is in value
|
229
|
+
val : anything
|
230
|
+
Result : Test
|
231
|
+
|
232
|
+
and(*operands) -- equivalent to self.eq(True).and(*operands)
|
233
|
+
operands : Test/Test
|
234
|
+
Result : Test
|
235
|
+
|
236
|
+
or(*operands) -- equivalent to self.eq(True).or(*operands)
|
237
|
+
operands : Test/Test
|
238
|
+
Result : Test
|
239
|
+
|
240
|
+
not
|
241
|
+
Result : Test -- equivalent to self.eq(True).not</code></pre>
|
242
|
+
|
243
|
+
|
244
|
+
<h3>Methods for all multi-element specifiers</h3>
|
245
|
+
|
246
|
+
<pre><code>MultipleElements < PositionSpecifier -- base class for all multi-
|
247
|
+
element reference forms
|
248
|
+
|
249
|
+
Methods:
|
250
|
+
|
251
|
+
first
|
252
|
+
Result : Element
|
253
|
+
|
254
|
+
middle
|
255
|
+
Result : Element
|
256
|
+
|
257
|
+
last
|
258
|
+
Result : Element
|
259
|
+
|
260
|
+
any
|
261
|
+
Result : Element
|
262
|
+
|
263
|
+
by_index(key)
|
264
|
+
key : integer -- normally an integer, though some apps may
|
265
|
+
accept other types (e.g. Finder accepts a MacTypes::Alias)
|
266
|
+
Result : ElementByIndex
|
267
|
+
|
268
|
+
by_name(key)
|
269
|
+
key : string -- the object's name
|
270
|
+
Result : ElementByName
|
271
|
+
|
272
|
+
by_id(key)
|
273
|
+
key : anything -- the object's unique id
|
274
|
+
Result : ElementByID
|
275
|
+
|
276
|
+
by_range(start_ref, end_ref)
|
277
|
+
start_ref : Element -- an app- or con-based reference
|
278
|
+
end_ref : Element -- an app- or con-based reference
|
279
|
+
Result : ElementByRange
|
280
|
+
|
281
|
+
by_filter(testref)
|
282
|
+
test_ref : Test -- an its-based reference
|
283
|
+
Result : ElementsByFilter</code></pre>
|
284
|
+
|
285
|
+
|
286
|
+
<h3>Methods for all test clause classes</h3>
|
287
|
+
|
288
|
+
<pre><code>Test < BASE -- represents a comparison/logic test
|
289
|
+
|
290
|
+
Methods:
|
291
|
+
|
292
|
+
and(*operands) -- apply a logical 'and' test to self and
|
293
|
+
one or more other operands
|
294
|
+
*operands : Test -- one or more comparison/logic test
|
295
|
+
objects
|
296
|
+
Result : Test
|
297
|
+
|
298
|
+
or(*operands) -- apply a logical 'or' test to self and one
|
299
|
+
or more other operands
|
300
|
+
*operands : Test -- one or more comparison/logic test
|
301
|
+
objects
|
302
|
+
Result : Test
|
303
|
+
|
304
|
+
not
|
305
|
+
Result : Test -- apply a logical 'not' test to self</code></pre>
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
<h2>Concrete classes</h2>
|
310
|
+
|
311
|
+
<h3>Insertion location reference form</h3>
|
312
|
+
|
313
|
+
<pre><code>InsertionSpecifier < Specifier -- refers to insertion point before or after/at
|
314
|
+
start or end of element(s); e.g. ref.before</code></pre>
|
315
|
+
|
316
|
+
<h3>Property reference forms</h3>
|
317
|
+
|
318
|
+
<pre><code>Property < PositionSpecifier -- refers to a property (whose value
|
319
|
+
may be a basic type, application object or reference);
|
320
|
+
e.g. ref.property('ctxt')
|
321
|
+
|
322
|
+
|
323
|
+
UserProperty < PositionSpecifier -- refers to a user-defined property
|
324
|
+
(typically in an OSA applet); e.g. ref.user_property('myVar')</code></pre>
|
325
|
+
|
326
|
+
|
327
|
+
<h3>Single element reference forms</h3>
|
328
|
+
|
329
|
+
|
330
|
+
<pre><code>ElementByIndex < SingleElement -- refers to a single element in the referenced
|
331
|
+
container object(s) by index; e.g. ref.by_index(3)
|
332
|
+
|
333
|
+
ElementByName < SingleElement -- refers to a single element in the referenced
|
334
|
+
container object(s) by name; e.g. ref.by_name('Documents')
|
335
|
+
|
336
|
+
|
337
|
+
ElementByID < SingleElement -- refers to a single element in the referenced container
|
338
|
+
object(s) by unique id; e.g. ref.by_id(3456)
|
339
|
+
|
340
|
+
|
341
|
+
ElementByOrdinal < SingleElement -- refers to first, middle, last or any element in
|
342
|
+
the referenced container object(s); e.g. ref.first
|
343
|
+
|
344
|
+
|
345
|
+
ElementByRelativePosition < SingleElement -- refers to the previous or next element
|
346
|
+
of the given class in the referenced container object(s);
|
347
|
+
e.g. ref.next('cpar')</code></pre>
|
348
|
+
|
349
|
+
|
350
|
+
<h3>Multiple element reference forms</h3>
|
351
|
+
|
352
|
+
<pre><code>ElementsByRange < MultipleElements -- refers to a range of elements
|
353
|
+
in the referenced container object(s) (including start and
|
354
|
+
end points); e.g. ref.by_range(AEM.con.elements('cpar').by_index(2),
|
355
|
+
AEM.con.elements('cpar').last)
|
356
|
+
|
357
|
+
|
358
|
+
ElementsByFilter < MultipleElements -- refers to all elements in the
|
359
|
+
referenced container object(s) that fulfill a given condition;
|
360
|
+
e.g. ref.by_filter(AEM.its.name.startswith('a'))
|
361
|
+
|
362
|
+
|
363
|
+
AllElements(MultipleElements) -- refers to all elements of
|
364
|
+
the given class in the referenced container object(s);
|
365
|
+
e.g. ref.elements('docu')</code></pre>
|
366
|
+
|
367
|
+
|
368
|
+
<h3>Tests</h3>
|
369
|
+
|
370
|
+
<p>The <code>Test</code> class represents a comparison test or logical test, and defines methods for composing additional logical tests on top of these. Each kind of test clause is represented by a different subclass of the main <code>Test</code> class. The details are not that important, however, so they're not listed here.</p>
|
371
|
+
|
372
|
+
|
373
|
+
|
374
|
+
|
375
|
+
<h3>Reference Roots</h3>
|
376
|
+
|
377
|
+
<pre><code>ApplicationRoot < PropertySpecifier -- AEM.app returns an instance of
|
378
|
+
this class
|
379
|
+
|
380
|
+
CurrentContainer < PropertySpecifier -- AEM.con returns an instance of
|
381
|
+
this class
|
382
|
+
|
383
|
+
ObjectBeingExamined < PropertySpecifier -- AEM.its returns an instance
|
384
|
+
of this class</code></pre>
|
385
|
+
|
386
|
+
|
387
|
+
|
388
|
+
<!-- TO DO: note on AEM_resolve -->
|
389
|
+
|
390
|
+
|
391
|
+
</div>
|
392
|
+
|
393
|
+
<!-- bottom navigation -->
|
394
|
+
<div class="navbar">
|
395
|
+
<a href="03_packingandunpackingdata.html">Previous</a> | <a href="index.html">Up</a> | <a href="05_targettingapplications.html">Next</a>
|
396
|
+
</div>
|
397
|
+
|
398
|
+
<!--footer-->
|
399
|
+
<p class="footer">© 2006 HAS</p>
|
400
|
+
</body>
|
401
|
+
</html>
|
@@ -0,0 +1,133 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
|
5
|
+
<title>aem | 5. Targetting Applications</title>
|
6
|
+
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<style type="text/css" media="all"><!--@import url(full.css);--></style>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<h1>5. Targetting Applications</h1>
|
14
|
+
|
15
|
+
<!-- top navigation -->
|
16
|
+
<div class="navbar">
|
17
|
+
<a href="04_references.html">Previous</a> | <a href="index.html">Up</a> | <a href="06_buildingandsendingevents.html">Next</a>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<!-- content -->
|
21
|
+
<div id="content">
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
<h2>The <code>Application</code> class</h2>
|
27
|
+
|
28
|
+
<p>The <code>Application</code> class represents an application to which Apple events will be sent. Its constructor allows applications to be identified in one of four ways: by full path, by eppc URL, by custom <code>AEAddressDesc</code>, or the host application if no other value is given. Its main method, <code>event</code>, is used to construct the Apple events to send. Several utility methods are also provided.</p>
|
29
|
+
|
30
|
+
<pre><code>Application -- the target application
|
31
|
+
|
32
|
+
Class methods:
|
33
|
+
|
34
|
+
launch(path) -- launch an application in background if not
|
35
|
+
already running, and send it a 'ascrnoop' event
|
36
|
+
path : string -- application's path, e.g. '/Applications/iCal.app'
|
37
|
+
|
38
|
+
is_running?(path) -- Is an application currently running?
|
39
|
+
path : string -- application's path, e.g. '/Applications/iCal.app'
|
40
|
+
Result : bool
|
41
|
+
|
42
|
+
Constructors:
|
43
|
+
|
44
|
+
by_path(path)
|
45
|
+
path : string -- full path to local application
|
46
|
+
(e.g. '/Applications/TextEdit.app')
|
47
|
+
|
48
|
+
by_pid(pid)
|
49
|
+
pid : integer -- Unix process id
|
50
|
+
|
51
|
+
by_url(url)
|
52
|
+
url : string -- url for remote process
|
53
|
+
(e.g. 'eppc://user:pass@0.0.0.1/TextEdit')
|
54
|
+
|
55
|
+
by_desc(desc)
|
56
|
+
desc : AEDesc -- AEAddressDesc for application
|
57
|
+
|
58
|
+
current -- the host process
|
59
|
+
|
60
|
+
Methods:
|
61
|
+
|
62
|
+
event(...) -- construct an Apple event (see next chapter for details)
|
63
|
+
|
64
|
+
start_transaction -- start a new transaction; all Events
|
65
|
+
constructed after start_transaction is called will
|
66
|
+
belong to the same transaction until end_transaction
|
67
|
+
or abort_transaction is called
|
68
|
+
|
69
|
+
end_transaction -- end the current transaction
|
70
|
+
|
71
|
+
abort_transaction -- abort the current transaction
|
72
|
+
|
73
|
+
reconnect -- Make sure this Application object has a valid
|
74
|
+
AEAddressDesc for the target application, relaunching
|
75
|
+
the target application if it's not currently running.
|
76
|
+
(Note: this only works for Application objects created
|
77
|
+
via the by_path constructor.)</code></pre>
|
78
|
+
|
79
|
+
|
80
|
+
<h2>Creating <code>Application</code> objects</h2>
|
81
|
+
|
82
|
+
<p>When targetting a local application by path, the full path to the application (or application bundle) must be given, including a <code>.app</code> suffix if present. Note that aem identifies local applications by process serial number for reliability. If the target application is not already running when a new <code>Application</code> instance is created, it will be started automatically so that a PSN can be acquired.</p>
|
83
|
+
|
84
|
+
<p>If the <code>by_url</code> constructor is used, its <code>url</code> argument should be an eppc URL string. Aem will pack this as an <code>AEDesc</code> of <code>typeApplSignature</code>. The target machine must have Remote Apple Events enabled in its Sharing preferences.</p>
|
85
|
+
|
86
|
+
<p>Clients can also supply their own <code>AEAddressDesc</code> if they prefer. This should be an <code>AE::AEDesc</code> of one of the following types:</p>
|
87
|
+
|
88
|
+
<pre><code>KAE::TypeApplicationBundleID
|
89
|
+
KAE::TypeApplicationURL
|
90
|
+
KAE::TypeApplSignature
|
91
|
+
KAE::TypeKernelProcessID
|
92
|
+
KAE::TypeMachPort
|
93
|
+
KAE::TypeProcessSerialNumber</code></pre>
|
94
|
+
|
95
|
+
<p>See the Apple Event Manager documentation for more information on these addressing modes.</p>
|
96
|
+
|
97
|
+
|
98
|
+
<h2>Launching applications</h2>
|
99
|
+
|
100
|
+
<p><code>Application.launch</code> is a class method attached to the <code>Application</code> class for convenience. It allows a non-running application to be launched without sending it the 'run' event (<code>aevtoapp</code>) normally sent to applications - a 'no-op' event (<code>ascrnoop</code>) is sent instead. It should be called before creating an <code>Application</code> object for the target application, otherwise the application will be launched as normal.</p>
|
101
|
+
|
102
|
+
|
103
|
+
<h2>Transactions</h2>
|
104
|
+
|
105
|
+
<p>The <code>start_transaction</code> and <code>end_transaction</code> methods are used to start and stop transaction sessions for applications that support this. All events <em>created</em> while a transaction session is active will be identified as part of that transaction.</p>
|
106
|
+
|
107
|
+
<p>Note that during a transaction, sending the application an event not created during that transaction will cause an error. Similarly, sending the application an event created during a transaction after that transaction has ended will cause an error.</p>
|
108
|
+
|
109
|
+
<p>The <code>end_transaction</code> method must be called to close both successful and failed transactions on completion. If a transaction session is accidentally left open, aem will attempt to close it when the <code>Application</code> object is garbage-collected, although this cannot be guaranteed to succeed.</p>
|
110
|
+
|
111
|
+
|
112
|
+
<h2>Reconnecting to local applications</h2>
|
113
|
+
|
114
|
+
<p>Because local applications are identified by process serial number, an existing <code>Application</code> object created using the <code>path</code> argument will no longer hold a valid <code>AEAddressDesc</code> if the target application quits. Sending events to an invalid address will cause a <code>CommandError</code> -600 ("application isn't running") or -609 ("connection is invalid") to be raised.</p>
|
115
|
+
|
116
|
+
<p>The <code>is_running?</code> class method can be used to check if a local application is running or not, given its full path.</p>
|
117
|
+
|
118
|
+
<p>Calling the <code>reconnect</code> method will create a new <code>AEAddressDesc</code> for an existing <code>Application</code> object. If the application is not running at the time, it will be started automatically.</p>
|
119
|
+
|
120
|
+
<p>Note that only <code>Event</code> instances created after <code>reconnect</code> is called will receive the new <code>AEAddressDesc</code>. Any <code>Event</code> instances created before <code>reconnect</code> is called will still contain the old <code>AEAddressDesc</code>. Also note that the <code>reconnect</code> method will only work for <code>Application</code> objects created using the <code>by_path</code> constructor.</p>
|
121
|
+
|
122
|
+
|
123
|
+
</div>
|
124
|
+
|
125
|
+
<!-- bottom navigation -->
|
126
|
+
<div class="navbar">
|
127
|
+
<a href="04_references.html">Previous</a> | <a href="index.html">Up</a> | <a href="06_buildingandsendingevents.html">Next</a>
|
128
|
+
</div>
|
129
|
+
|
130
|
+
<!--footer-->
|
131
|
+
<p class="footer">© 2006 HAS</p>
|
132
|
+
</body>
|
133
|
+
</html>
|