1 """aetypes - Python objects representing various AE types."""
3 from AppleEvents
import *
4 from AERegistry
import *
5 from AEObjects
import *
11 # convoluted, since there are cyclic dependencies between this file and
15 from aepack
import pack
16 return apply(pack
, args
)
18 def IsSubclass(cls
, base
):
19 """Test whether CLASS1 is the same as or a subclass of CLASS2"""
20 # Loop to optimize for single inheritance
22 if cls
is base
: return 1
23 if len(cls
.__bases
__) <> 1: break
24 cls
= cls
.__bases
__[0]
25 # Recurse to cope with multiple inheritance
26 for c
in cls
.__bases
__:
27 if IsSubclass(c
, base
): return 1
30 def IsInstance(x
, cls
):
31 """Test whether OBJECT is an instance of (a subclass of) CLASS"""
32 return type(x
) is InstanceType
and IsSubclass(x
.__class
__, cls
)
35 """'nice' representation of an object"""
36 if type(s
) is StringType
: return repr(s
)
40 """An uninterpreted AE object"""
42 def __init__(self
, type, data
):
47 return "Unknown(%s, %s)" % (`self
.type`
, `self
.data`
)
50 return pack(self
.data
, self
.type)
53 """An AE enumeration value"""
55 def __init__(self
, enum
):
56 self
.enum
= "%-4.4s" % str(enum
)
59 return "Enum(%s)" % `self
.enum`
62 return string
.strip(self
.enum
)
65 return pack(self
.enum
, typeEnumeration
)
68 return IsInstance(x
, Enum
)
71 if IsEnum(enum
): return enum
75 """An AE boolean value"""
77 def __init__(self
, bool):
78 self
.bool = (not not bool)
81 return "Boolean(%s)" % `self
.bool`
90 return pack(struct
.pack('b', self
.bool), 'bool')
93 return IsInstance(x
, Boolean
)
96 if IsBoolean(bool): return bool
100 """An AE 4-char typename object"""
102 def __init__(self
, type):
103 self
.type = "%-4.4s" % str(type)
106 return "Type(%s)" % `self
.type`
109 return string
.strip(self
.type)
111 def __aepack__(self
):
112 return pack(self
.type, typeType
)
115 return IsInstance(x
, Type
)
118 if IsType(type): return type
123 """An AE 4-char keyword object"""
125 def __init__(self
, keyword
):
126 self
.keyword
= "%-4.4s" % str(keyword
)
129 return "Keyword(%s)" % `self
.keyword`
132 return string
.strip(self
.keyword
)
134 def __aepack__(self
):
135 return pack(self
.keyword
, typeKeyword
)
138 return IsInstance(x
, Keyword
)
141 """An AE range object"""
143 def __init__(self
, start
, stop
):
148 return "Range(%s, %s)" % (`self
.start`
, `self
.stop`
)
151 return "%s thru %s" % (nice(self
.start
), nice(self
.stop
))
153 def __aepack__(self
):
154 return pack({'star': self
.start
, 'stop': self
.stop
}, 'rang')
157 return IsInstance(x
, Range
)
160 """An AE Comparison"""
162 def __init__(self
, obj1
, relo
, obj2
):
164 self
.relo
= "%-4.4s" % str(relo
)
168 return "Comparison(%s, %s, %s)" % (`self
.obj1`
, `self
.relo`
, `self
.obj2`
)
171 return "%s %s %s" % (nice(self
.obj1
), string
.strip(self
.relo
), nice(self
.obj2
))
173 def __aepack__(self
):
174 return pack({'obj1': self
.obj1
,
175 'relo': mkenum(self
.relo
),
180 return IsInstance(x
, Comparison
)
182 class NComparison(Comparison
):
183 # The class attribute 'relo' must be set in a subclass
185 def __init__(self
, obj1
, obj2
):
186 Comparison
.__init
__(obj1
, self
.relo
, obj2
)
191 def __init__(self
, abso
):
193 self
.abso
= "%-4.4s" % str(abso
)
196 return "Ordinal(%s)" % (`self
.abso`
)
199 return "%s" % (string
.strip(self
.abso
))
201 def __aepack__(self
):
202 return pack(self
.abso
, 'abso')
205 return IsInstance(x
, Ordinal
)
207 class NOrdinal(Ordinal
):
208 # The class attribute 'abso' must be set in a subclass
211 Ordinal
.__init
__(self
, self
.abso
)
214 """An AE logical expression object"""
216 def __init__(self
, logc
, term
):
217 self
.logc
= "%-4.4s" % str(logc
)
221 return "Logical(%s, %s)" % (`self
.logc`
, `self
.term`
)
224 if type(self
.term
) == ListType
and len(self
.term
) == 2:
225 return "%s %s %s" % (nice(self
.term
[0]),
226 string
.strip(self
.logc
),
229 return "%s(%s)" % (string
.strip(self
.logc
), nice(self
.term
))
231 def __aepack__(self
):
232 return pack({'logc': mkenum(self
.logc
), 'term': self
.term
}, 'logi')
235 return IsInstance(x
, Logical
)
238 """An AE object respresenting text in a certain style"""
240 def __init__(self
, style
, text
):
245 return "StyledText(%s, %s)" % (`self
.style`
, `self
.text`
)
250 def __aepack__(self
):
251 return pack({'ksty': self
.style
, 'ktxt': self
.text
}, 'STXT')
254 return IsInstance(x
, StyledText
)
257 """An AE text object with style, script and language specified"""
259 def __init__(self
, script
, style
, text
):
265 return "AEText(%s, %s, %s)" % (`self
.script`
, `self
.style`
, `self
.text`
)
270 def __aepack__(self
):
271 return pack({keyAEScriptTag
: self
.script
, keyAEStyles
: self
.style
,
272 keyAEText
: self
.text
}, typeAEText
)
275 return IsInstance(x
, AEText
)
278 """A text object with script and language specified"""
280 def __init__(self
, script
, language
, text
):
282 self
.language
= language
286 return "IntlText(%s, %s, %s)" % (`self
.script`
, `self
.language`
, `self
.text`
)
291 def __aepack__(self
):
292 return pack(struct
.pack('hh', self
.script
, self
.language
)+self
.text
,
296 return IsInstance(x
, IntlText
)
298 class IntlWritingCode
:
299 """An object representing script and language"""
301 def __init__(self
, script
, language
):
303 self
.language
= language
306 return "IntlWritingCode(%s, %s)" % (`self
.script`
, `self
.language`
)
309 return "script system %d, language %d"%(self
.script
, self
.language
)
311 def __aepack__(self
):
312 return pack(struct
.pack('hh', self
.script
, self
.language
),
315 def IsIntlWritingCode(x
):
316 return IsInstance(x
, IntlWritingCode
)
321 def __init__(self
, v
, h
):
326 return "QDPoint(%s, %s)" % (`self
.v`
, `self
.h`
)
329 return "(%d, %d)"%(self
.v
, self
.h
)
331 def __aepack__(self
):
332 return pack(struct
.pack('hh', self
.v
, self
.h
),
336 return IsInstance(x
, QDPoint
)
341 def __init__(self
, v0
, h0
, v1
, h1
):
348 return "QDRectangle(%s, %s, %s, %s)" % (`self
.v0`
, `self
.h0`
,
349 `self
.v1`
, `self
.h1`
)
352 return "(%d, %d)-(%d, %d)"%(self
.v0
, self
.h0
, self
.v1
, self
.h1
)
354 def __aepack__(self
):
355 return pack(struct
.pack('hhhh', self
.v0
, self
.h0
, self
.v1
, self
.h1
),
358 def IsQDRectangle(x
):
359 return IsInstance(x
, QDRectangle
)
364 def __init__(self
, r
, g
, b
):
370 return "RGBColor(%s, %s, %s)" % (`self
.r`
, `self
.g`
, `self
.b`
)
373 return "0x%x red, 0x%x green, 0x%x blue"% (self
.r
, self
.g
, self
.b
)
375 def __aepack__(self
):
376 return pack(struct
.pack('hhh', self
.r
, self
.g
, self
.b
),
380 return IsInstance(x
, RGBColor
)
382 class ObjectSpecifier
:
384 """A class for constructing and manipulation AE object specifiers in python.
386 An object specifier is actually a record with four fields:
391 'want' type 4-char class code of thing we want,
392 e.g. word, paragraph or property
394 'form' enum how we specify which 'want' thing(s) we want,
395 e.g. by index, by range, by name, or by property specifier
397 'seld' any which thing(s) we want,
398 e.g. its index, its name, or its property specifier
400 'from' object the object in which it is contained,
401 or null, meaning look for it in the application
403 Note that we don't call this class plain "Object", since that name
404 is likely to be used by the application.
407 def __init__(self
, want
, form
, seld
, fr
= None):
414 s
= "ObjectSpecifier(%s, %s, %s" % (`self
.want`
, `self
.form`
, `self
.seld`
)
416 s
= s
+ ", %s)" % `self
.fr`
421 def __aepack__(self
):
422 return pack({'want': mktype(self
.want
),
423 'form': mkenum(self
.form
),
428 def IsObjectSpecifier(x
):
429 return IsInstance(x
, ObjectSpecifier
)
432 # Backwards compatability, sigh...
433 class Property(ObjectSpecifier
):
435 def __init__(self
, which
, fr
= None, want
='prop'):
436 ObjectSpecifier
.__init
__(self
, want
, 'prop', mktype(which
), fr
)
440 return "Property(%s, %s)" % (`self
.seld
.type`
, `self
.fr`
)
442 return "Property(%s)" % `self
.seld
.type`
446 return "Property %s of %s" % (str(self
.seld
), str(self
.fr
))
448 return "Property %s" % str(self
.seld
)
451 class NProperty(ObjectSpecifier
):
452 # Subclasses *must* self baseclass attributes:
453 # want is the type of this property
454 # which is the property name of this property
456 def __init__(self
, fr
= None):
462 ObjectSpecifier
.__init
__(self
, self
.want
, 'prop',
463 mktype(self
.which
), fr
)
466 rv
= "Property(%s"%`self
.seld
.type`
468 rv
= rv
+ ", fr=%s" % `self
.fr`
469 if self
.want
!= 'prop':
470 rv
= rv
+ ", want=%s" % `self
.want`
475 return "Property %s of %s" % (str(self
.seld
), str(self
.fr
))
477 return "Property %s" % str(self
.seld
)
480 class SelectableItem(ObjectSpecifier
):
482 def __init__(self
, want
, seld
, fr
= None):
488 elif IsComparison(seld
) or IsLogical(seld
):
491 # Breakout: specify both form and seld in a tuple
492 # (if you want ID or rele or somesuch)
496 ObjectSpecifier
.__init
__(self
, want
, form
, seld
, fr
)
499 class ComponentItem(SelectableItem
):
500 # Derived classes *must* set the *class attribute* 'want' to some constant
501 # Also, dictionaries _propdict and _elemdict must be set to map property
502 # and element names to the correct classes
504 def __init__(self
, which
, fr
= None):
505 SelectableItem
.__init
__(self
, self
.want
, which
, fr
)
509 return "%s(%s)" % (self
.__class
__.__name
__, `self
.seld`
)
510 return "%s(%s, %s)" % (self
.__class
__.__name
__, `self
.seld`
, `self
.fr`
)
514 if type(seld
) == StringType
:
517 start
, stop
= seld
.start
, seld
.stop
518 if type(start
) == InstanceType
== type(stop
) and \
519 start
.__class
__ == self
.__class
__ == stop
.__class
__:
520 ss
= str(start
.seld
) + " thru " + str(stop
.seld
)
525 s
= "%s %s" % (self
.__class
__.__name
__, ss
)
526 if self
.fr
: s
= s
+ " of %s" % str(self
.fr
)
529 def __getattr__(self
, name
):
530 if self
._elemdict
.has_key(name
):
531 cls
= self
._elemdict
[name
]
532 return DelayedComponentItem(cls
, self
)
533 if self
._propdict
.has_key(name
):
534 cls
= self
._propdict
[name
]
536 raise AttributeError, name
539 class DelayedComponentItem
:
540 def __init__(self
, compclass
, fr
):
541 self
.compclass
= compclass
544 def __call__(self
, which
):
545 return self
.compclass(which
, self
.fr
)
548 return "%s(???, %s)" % (self
.__class
__.__name
__, `self
.fr`
)
551 return "selector for element %s of %s"%(self
.__class
__.__name
__, str(self
.fr
))
554 class %s(ComponentItem): want = '%s'
557 exec template
% ("Text", 'text')
558 exec template
% ("Character", 'cha ')
559 exec template
% ("Word", 'cwor')
560 exec template
% ("Line", 'clin')
561 exec template
% ("paragraph", 'cpar')
562 exec template
% ("Window", 'cwin')
563 exec template
% ("Document", 'docu')
564 exec template
% ("File", 'file')
565 exec template
% ("InsertionPoint", 'cins')