Another batch of updates...
[python/dscho.git] / Mac / Lib / toolbox / aetypes.py
blobe0a466f781eab6d3bb006f734cbef4088c9b5494
1 """aetypes - Python objects representing various AE types."""
3 from AppleEvents import *
4 from AERegistry import *
5 from AEObjects import *
6 import struct
7 from types import *
8 import string
11 # convoluted, since there are cyclic dependencies between this file and
12 # aetools_convert.
14 def pack(*args):
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
21 while 1:
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
28 return 0
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)
34 def nice(s):
35 """'nice' representation of an object"""
36 if type(s) is StringType: return repr(s)
37 else: return str(s)
39 class Unknown:
40 """An uninterpreted AE object"""
42 def __init__(self, type, data):
43 self.type = type
44 self.data = data
46 def __repr__(self):
47 return "Unknown(%s, %s)" % (`self.type`, `self.data`)
49 def __aepack__(self):
50 return pack(self.data, self.type)
52 class Enum:
53 """An AE enumeration value"""
55 def __init__(self, enum):
56 self.enum = "%-4.4s" % str(enum)
58 def __repr__(self):
59 return "Enum(%s)" % `self.enum`
61 def __str__(self):
62 return string.strip(self.enum)
64 def __aepack__(self):
65 return pack(self.enum, typeEnumeration)
67 def IsEnum(x):
68 return IsInstance(x, Enum)
70 def mkenum(enum):
71 if IsEnum(enum): return enum
72 return Enum(enum)
74 class Type:
75 """An AE 4-char typename object"""
77 def __init__(self, type):
78 self.type = "%-4.4s" % str(type)
80 def __repr__(self):
81 return "Type(%s)" % `self.type`
83 def __str__(self):
84 return string.strip(self.type)
86 def __aepack__(self):
87 return pack(self.type, typeType)
89 def IsType(x):
90 return IsInstance(x, Type)
92 def mktype(type):
93 if IsType(type): return type
94 return Type(type)
97 class Keyword:
98 """An AE 4-char keyword object"""
100 def __init__(self, keyword):
101 self.keyword = "%-4.4s" % str(keyword)
103 def __repr__(self):
104 return "Keyword(%s)" % `self.keyword`
106 def __str__(self):
107 return string.strip(self.keyword)
109 def __aepack__(self):
110 return pack(self.keyword, typeKeyword)
112 def IsKeyword(x):
113 return IsInstance(x, Keyword)
115 class Range:
116 """An AE range object"""
118 def __init__(self, start, stop):
119 self.start = start
120 self.stop = stop
122 def __repr__(self):
123 return "Range(%s, %s)" % (`self.start`, `self.stop`)
125 def __str__(self):
126 return "%s thru %s" % (nice(self.start), nice(self.stop))
128 def __aepack__(self):
129 return pack({'star': self.start, 'stop': self.stop}, 'rang')
131 def IsRange(x):
132 return IsInstance(x, Range)
134 class Comparison:
135 """An AE Comparison"""
137 def __init__(self, obj1, relo, obj2):
138 self.obj1 = obj1
139 self.relo = "%-4.4s" % str(relo)
140 self.obj2 = obj2
142 def __repr__(self):
143 return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
145 def __str__(self):
146 return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
148 def __aepack__(self):
149 return pack({'obj1': self.obj1,
150 'relo': mkenum(self.relo),
151 'obj2': self.obj2},
152 'cmpd')
154 def IsComparison(x):
155 return IsInstance(x, Comparison)
157 class Logical:
158 """An AE logical expression object"""
160 def __init__(self, logc, term):
161 self.logc = "%-4.4s" % str(logc)
162 self.term = term
164 def __repr__(self):
165 return "Logical(%s, %s)" % (`self.logc`, `self.term`)
167 def __str__(self):
168 if type(self.term) == ListType and len(self.term) == 2:
169 return "%s %s %s" % (nice(self.term[0]),
170 string.strip(self.logc),
171 nice(self.term[1]))
172 else:
173 return "%s(%s)" % (string.strip(self.logc), nice(self.term))
175 def __aepack__(self):
176 return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
178 def IsLogical(x):
179 return IsInstance(x, Logical)
181 class StyledText:
182 """An AE object respresenting text in a certain style"""
184 def __init__(self, style, text):
185 self.style = style
186 self.text = text
188 def __repr__(self):
189 return "StyledText(%s, %s)" % (`self.style`, `self.text`)
191 def __str__(self):
192 return self.text
194 def __aepack__(self):
195 return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
197 def IsStyledText(x):
198 return IsInstance(x, StyledText)
200 class AEText:
201 """An AE text object with style, script and language specified"""
203 def __init__(self, script, style, text):
204 self.script = script
205 self.style = style
206 self.text = text
208 def __repr__(self):
209 return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
211 def __str__(self):
212 return self.text
214 def __aepack__(self):
215 return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
216 keyAEText: self.text}, typeAEText)
218 def IsAEText(x):
219 return IsInstance(x, AEText)
221 class IntlText:
222 """A text object with script and language specified"""
224 def __init__(self, script, language, text):
225 self.script = script
226 self.language = language
227 self.text = text
229 def __repr__(self):
230 return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
232 def __str__(self):
233 return self.text
235 def __aepack__(self):
236 return pack(struct.pack('hh', self.script, self.language)+self.text,
237 typeIntlText)
239 def IsIntlText(x):
240 return IsInstance(x, IntlText)
242 class IntlWritingCode:
243 """An object representing script and language"""
245 def __init__(self, script, language):
246 self.script = script
247 self.language = language
249 def __repr__(self):
250 return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
252 def __str__(self):
253 return "script system %d, language %d"%(self.script, self.language)
255 def __aepack__(self):
256 return pack(struct.pack('hh', self.script, self.language),
257 typeIntlWritingCode)
259 def IsIntlWritingCode(x):
260 return IsInstance(x, IntlWritingCode)
262 class QDPoint:
263 """A point"""
265 def __init__(self, v, h):
266 self.v = v
267 self.h = h
269 def __repr__(self):
270 return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
272 def __str__(self):
273 return "(%d, %d)"%(self.v, self.h)
275 def __aepack__(self):
276 return pack(struct.pack('hh', self.v, self.h),
277 typeQDPoint)
279 def IsQDPoint(x):
280 return IsInstance(x, QDPoint)
282 class QDRectangle:
283 """A rectangle"""
285 def __init__(self, v0, h0, v1, h1):
286 self.v0 = v0
287 self.h0 = h0
288 self.v1 = v1
289 self.h1 = h1
291 def __repr__(self):
292 return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
293 `self.v1`, `self.h1`)
295 def __str__(self):
296 return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
298 def __aepack__(self):
299 return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
300 typeQDRectangle)
302 def IsQDRectangle(x):
303 return IsInstance(x, QDRectangle)
305 class RGBColor:
306 """An RGB color"""
308 def __init__(self, r, g, b):
309 self.r = r
310 self.g = g
311 self.b = b
313 def __repr__(self):
314 return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
316 def __str__(self):
317 return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
319 def __aepack__(self):
320 return pack(struct.pack('hhh', self.r, self.g, self.b),
321 typeRGBColor)
323 def IsRGBColor(x):
324 return IsInstance(x, RGBColor)
326 class ObjectSpecifier:
328 """A class for constructing and manipulation AE object specifiers in python.
330 An object specifier is actually a record with four fields:
332 key type description
333 --- ---- -----------
335 'want' type what kind of thing we want,
336 e.g. word, paragraph or property
338 'form' enum how we specify the thing(s) we want,
339 e.g. by index, by range, by name, or by property specifier
341 'seld' any which thing(s) we want,
342 e.g. its index, its name, or its property specifier
344 'from' object the object in which it is contained,
345 or null, meaning look for it in the application
347 Note that we don't call this class plain "Object", since that name
348 is likely to be used by the application.
351 def __init__(self, want, form, seld, fr = None):
352 self.want = want
353 self.form = form
354 self.seld = seld
355 self.fr = fr
357 def __repr__(self):
358 s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
359 if self.fr:
360 s = s + ", %s)" % `self.fr`
361 else:
362 s = s + ")"
363 return s
365 def __aepack__(self):
366 return pack({'want': mktype(self.want),
367 'form': mkenum(self.form),
368 'seld': self.seld,
369 'from': self.fr},
370 'obj ')
373 def IsObjectSpecifier(x):
374 return IsInstance(x, ObjectSpecifier)
377 class Property(ObjectSpecifier):
379 def __init__(self, which, fr = None):
380 ObjectSpecifier.__init__(self, 'prop', 'prop', mkenum(which), fr)
382 def __repr__(self):
383 if self.fr:
384 return "Property(%s, %s)" % (`self.seld.enum`, `self.fr`)
385 else:
386 return "Property(%s)" % `self.seld.enum`
388 def __str__(self):
389 if self.fr:
390 return "Property %s of %s" % (str(self.seld), str(self.fr))
391 else:
392 return "Property %s" % str(self.seld)
395 class SelectableItem(ObjectSpecifier):
397 def __init__(self, want, seld, fr = None):
398 t = type(seld)
399 if t == StringType:
400 form = 'name'
401 elif IsRange(seld):
402 form = 'rang'
403 elif IsComparison(seld) or IsLogical(seld):
404 form = 'test'
405 else:
406 form = 'indx'
407 ObjectSpecifier.__init__(self, want, form, seld, fr)
410 class ComponentItem(SelectableItem):
411 # Derived classes *must* set the *class attribute* 'want' to some constant
413 def __init__(self, which, fr = None):
414 SelectableItem.__init__(self, self.want, which, fr)
416 def __repr__(self):
417 if not self.fr:
418 return "%s(%s)" % (self.__class__.__name__, `self.seld`)
419 return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
421 def __str__(self):
422 seld = self.seld
423 if type(seld) == StringType:
424 ss = repr(seld)
425 elif IsRange(seld):
426 start, stop = seld.start, seld.stop
427 if type(start) == InstanceType == type(stop) and \
428 start.__class__ == self.__class__ == stop.__class__:
429 ss = str(start.seld) + " thru " + str(stop.seld)
430 else:
431 ss = str(seld)
432 else:
433 ss = str(seld)
434 s = "%s %s" % (self.__class__.__name__, ss)
435 if self.fr: s = s + " of %s" % str(self.fr)
436 return s
439 template = """
440 class %s(ComponentItem): want = '%s'
443 exec template % ("Text", 'text')
444 exec template % ("Character", 'cha ')
445 exec template % ("Word", 'cwor')
446 exec template % ("Line", 'clin')
447 exec template % ("Paragraph", 'cpar')
448 exec template % ("Window", 'cwin')
449 exec template % ("Document", 'docu')
450 exec template % ("File", 'file')
451 exec template % ("InsertionPoint", 'cins')