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
)
72 if IsEnum(enum
): return enum
76 """An AE boolean value"""
78 def __init__(self
, bool):
80 self
.bool = "%-4.4s" % str(typeTrue
)
82 self
.bool = "%-4.4s" % str(typeFalse
)
85 return "Boolean(%s)" % self
.bool
91 if self
.bool == 'true':
92 return pack('', typeTrue
)
94 return pack('', typeFalse
)
97 return IsInstance(x
, Boolean
)
101 if IsBoolean(bool): return bool
105 """An AE 4-char typename object"""
107 def __init__(self
, _type
):
108 self
.type = "%-4.4s" % str(_type
)
111 return "Type(%s)" % `self
.type`
114 return string
.strip(self
.type)
116 def __aepack__(self
):
117 # print self.type, typeType
118 return pack(self
.type, typeType
)
121 return IsInstance(x
, Type
)
124 # Should check for apple ID codes, will allow
125 if IsType(_type
): return _type
126 if type(_type
) <> StringType
: return _type
127 if len(_type
) <> 4: return Type(eval('type' + _type
))
132 """An AE 4-char keyword object"""
134 def __init__(self
, keyword
):
135 self
.keyword
= "%-4.4s" % str(keyword
)
138 return "Keyword(%s)" % `self
.keyword`
141 return string
.strip(self
.keyword
)
143 def __aepack__(self
):
144 return pack(self
.keyword
, typeKeyword
)
147 return IsInstance(x
, Keyword
)
150 """An AE range object"""
152 def __init__(self
, start
, stop
):
157 return "Range(%s, %s)" % (`self
.start`
, `self
.stop`
)
160 return "%s thru %s" % (nice(self
.start
), nice(self
.stop
))
162 def __aepack__(self
):
163 return pack({'star': self
.start
, 'stop': self
.stop
}, 'rang')
166 return IsInstance(x
, Range
)
169 """An AE Comparison"""
171 def __init__(self
, obj1
, relo
, obj2
):
173 self
.relo
= "%-4.4s" % str(relo
)
177 return "Comparison(%s, %s, %s)" % (`self
.obj1`
, `self
.relo`
, `self
.obj2`
)
180 return "%s %s %s" % (nice(self
.obj1
), string
.strip(self
.relo
), nice(self
.obj2
))
182 def __aepack__(self
):
183 return pack({'obj1': self
.obj1
,
184 'relo': mkenum(self
.relo
),
189 return IsInstance(x
, Comparison
)
191 class NComparison(Comparison
):
192 # The class attribute 'relo' must be set in a subclass
194 def __init__(self
, obj1
, obj2
):
195 Comparison
.__init
__(obj1
, self
.relo
, obj2
)
200 def __init__(self
, ord):
204 return "baetypes.Ordinal(%s)" % `self
.ord`
207 return "%s" % (string
.strip(self
.ord))
209 def __aepack__(self
):
210 return pack(self
.ord, typeAbsoluteOrdinal
)
213 # print 'IsOrdinal', x, IsInstance(x, Ordinal)
214 return IsInstance(x
, Ordinal
)
217 if IsOrdinal(Ord
): return Ord
222 class NOrdinal(Ordinal
):
223 # The class attribute 'abso' must be set in a subclass
226 # print 'NOrdinal', self.abso
227 Ordinal
.__init
__(self
, self
.abso
)
230 """An AE logical expression object"""
232 def __init__(self
, logc
, term
):
233 self
.logc
= "%-4.4s" % str(logc
)
237 return "Logical(%s, %s)" % (`self
.logc`
, `self
.term`
)
240 if type(self
.term
) == ListType
and len(self
.term
) == 2:
241 return "%s %s %s" % (nice(self
.term
[0]),
242 string
.strip(self
.logc
),
245 return "%s(%s)" % (string
.strip(self
.logc
), nice(self
.term
))
247 def __aepack__(self
):
248 return pack({'logc': mkenum(self
.logc
), 'term': self
.term
}, 'logi')
251 return IsInstance(x
, Logical
)
254 """An AE object respresenting text in a certain style"""
256 def __init__(self
, style
, text
):
261 return "StyledText(%s, %s)" % (`self
.style`
, `self
.text`
)
266 def __aepack__(self
):
267 return pack({'ksty': self
.style
, 'ktxt': self
.text
}, 'STXT')
270 return IsInstance(x
, StyledText
)
273 """An AE text object with style, script and language specified"""
275 def __init__(self
, script
, style
, text
):
281 return "AEText(%s, %s, %s)" % (`self
.script`
, `self
.style`
, `self
.text`
)
286 def __aepack__(self
):
287 return pack({keyAEScriptTag
: self
.script
, keyAEStyles
: self
.style
,
288 keyAEText
: self
.text
}, typeAEText
)
291 return IsInstance(x
, AEText
)
294 """A text object with script and language specified"""
296 def __init__(self
, script
, language
, text
):
298 self
.language
= language
302 return "IntlText(%s, %s, %s)" % (`self
.script`
, `self
.language`
, `self
.text`
)
307 def __aepack__(self
):
308 return pack(struct
.pack('hh', self
.script
, self
.language
)+self
.text
,
312 return IsInstance(x
, IntlText
)
314 class IntlWritingCode
:
315 """An object representing script and language"""
317 def __init__(self
, script
, language
):
319 self
.language
= language
322 return "IntlWritingCode(%s, %s)" % (`self
.script`
, `self
.language`
)
325 return "script system %d, language %d"%(self
.script
, self
.language
)
327 def __aepack__(self
):
328 return pack(struct
.pack('hh', self
.script
, self
.language
),
331 def IsIntlWritingCode(x
):
332 return IsInstance(x
, IntlWritingCode
)
337 def __init__(self
, v
, h
):
342 return "QDPoint(%s, %s)" % (`self
.v`
, `self
.h`
)
345 return "(%d, %d)"%(self
.v
, self
.h
)
347 def __aepack__(self
):
348 return pack(struct
.pack('hh', self
.v
, self
.h
),
352 return IsInstance(x
, QDPoint
)
357 def __init__(self
, v0
, h0
, v1
, h1
):
364 return "QDRectangle(%s, %s, %s, %s)" % (`self
.v0`
, `self
.h0`
,
365 `self
.v1`
, `self
.h1`
)
368 return "(%d, %d)-(%d, %d)"%(self
.v0
, self
.h0
, self
.v1
, self
.h1
)
370 def __aepack__(self
):
371 return pack(struct
.pack('hhhh', self
.v0
, self
.h0
, self
.v1
, self
.h1
),
374 def IsQDRectangle(x
):
375 return IsInstance(x
, QDRectangle
)
380 def __init__(self
, r
, g
, b
):
386 return "RGBColor(%s, %s, %s)" % (`self
.r`
, `self
.g`
, `self
.b`
)
389 return "0x%x red, 0x%x green, 0x%x blue"% (self
.r
, self
.g
, self
.b
)
391 def __aepack__(self
):
392 return pack(struct
.pack('hhh', self
.r
, self
.g
, self
.b
),
396 return IsInstance(x
, RGBColor
)
398 class ObjectSpecifier
:
400 """A class for constructing and manipulation AE object specifiers in python.
402 An object specifier is actually a record with four fields:
407 'want' type 4-char class code of thing we want,
408 e.g. word, paragraph or property
410 'form' enum how we specify which 'want' thing(s) we want,
411 e.g. by index, by range, by name, or by property specifier
413 'seld' any which thing(s) we want,
414 e.g. its index, its name, or its property specifier
416 'from' object the object in which it is contained,
417 or null, meaning look for it in the application
419 Note that we don't call this class plain "Object", since that name
420 is likely to be used by the application.
423 def __init__(self
, want
, form
, seld
, fr
= None):
430 s
= "ObjectSpecifier(%s, %s, %s" % (`self
.want`
, `self
.form`
, `self
.seld`
)
432 s
= s
+ ", %s)" % `self
.fr`
437 def __aepack__(self
):
438 return pack({'want': mktype(self
.want
),
439 'form': mkenum(self
.form
),
444 def IsObjectSpecifier(x
):
445 return IsInstance(x
, ObjectSpecifier
)
448 # Backwards compatability, sigh...
449 class Property(ObjectSpecifier
):
451 def __init__(self
, which
, fr
= None, want
='prop'):
452 ObjectSpecifier
.__init
__(self
, want
, 'prop', mktype(which
), fr
)
456 return "Property_r(%s, %s)" % (`self
.seld
.type`
, `self
.fr`
)
458 return "Property_r(%s)" % `self
.seld
.type`
462 return "Property %s of %s" % (str(self
.seld
), str(self
.fr
))
464 return "Property_s %s" % str(self
.seld
)
467 class NProperty(ObjectSpecifier
):
468 # Subclasses *must* self baseclass attributes:
469 # want is the type of this property
470 # which is the property name of this property
472 def __init__(self
, want
, form
, seld
, fr
= None):
473 ObjectSpecifier
.__init
__(self
, want
, form
,
477 class SelectableItem(ObjectSpecifier
):
479 def __init__(self
, want
, seld
, fr
= None):
485 elif IsComparison(seld
) or IsLogical(seld
):
488 # Breakout: specify both form and seld in a tuple
489 # (if you want ID or rele or somesuch)
493 ObjectSpecifier
.__init
__(self
, want
, form
, seld
, fr
)
496 class ComponentItem(SelectableItem
):
497 # Derived classes *must* set the *class attribute* 'want' to some constant
498 # Also, dictionaries _propdict and _elemdict must be set to map property
499 # and element names to the correct classes
501 def __init__(self
, want
, which
, fr
= None):
502 SelectableItem
.__init
__(self
, want
, which
, fr
)
506 return "%s(%s)" % (self
.__class
__.__name
__, `self
.seld`
)
507 return "%s(%s, %s)" % (self
.__class
__.__name
__, `self
.seld`
, `self
.fr`
)
511 if type(seld
) == StringType
:
514 start
, stop
= seld
.start
, seld
.stop
515 if type(start
) == InstanceType
== type(stop
) and \
516 start
.__class
__ == self
.__class
__ == stop
.__class
__:
517 ss
= str(start
.seld
) + " thru " + str(stop
.seld
)
522 s
= "%s %s" % (self
.__class
__.__name
__, ss
)
523 if self
.fr
: s
= s
+ " of %s" % str(self
.fr
)
526 # def __getattr__(self, name):
528 # if self._elemdict.has_key(name):
529 # cls = self._elemdict[name]
530 # return DelayedComponentItem(cls, self)
531 # if self._propdict.has_key(name):
532 # cls = self._propdict[name]
534 # raise AttributeError, name
537 class DelayedComponentItem
:
538 def __init__(self
, compclass
, fr
):
539 self
.compclass
= compclass
542 def __call__(self
, which
):
543 return self
.compclass(which
, self
.fr
)
546 return "%s(???, %s)" % (self
.__class
__.__name
__, `self
.fr`
)
549 return "selector for element %s of %s"%(self
.__class
__.__name
__, str(self
.fr
))
552 class %s(ComponentItem): want = '%s'
555 exec template
% ("Text", 'text')
556 exec template
% ("Character", 'cha ')
557 exec template
% ("Word", 'cwor')
558 exec template
% ("Line", 'clin')
559 exec template
% ("paragraph", 'cpar')
560 exec template
% ("Window", 'cwin')
561 exec template
% ("Document", 'docu')
562 exec template
% ("File", 'file')
563 exec template
% ("InsertionPoint", 'cins')