Fix sf bug 666219: assertion error in httplib.
[python/dscho.git] / Lib / plat-mac / aetypes.py
blob538cf14e64ba12c3cb0f8b9bee70f24d828b864d
1 """aetypes - Python objects representing various AE types."""
3 from Carbon.AppleEvents import *
4 import struct
5 from types import *
6 import string
9 # convoluted, since there are cyclic dependencies between this file and
10 # aetools_convert.
12 def pack(*args, **kwargs):
13 from aepack import pack
14 return pack( *args, **kwargs)
16 def nice(s):
17 """'nice' representation of an object"""
18 if type(s) is StringType: return repr(s)
19 else: return str(s)
21 class Unknown:
22 """An uninterpreted AE object"""
24 def __init__(self, type, data):
25 self.type = type
26 self.data = data
28 def __repr__(self):
29 return "Unknown(%s, %s)" % (`self.type`, `self.data`)
31 def __aepack__(self):
32 return pack(self.data, self.type)
34 class Enum:
35 """An AE enumeration value"""
37 def __init__(self, enum):
38 self.enum = "%-4.4s" % str(enum)
40 def __repr__(self):
41 return "Enum(%s)" % `self.enum`
43 def __str__(self):
44 return string.strip(self.enum)
46 def __aepack__(self):
47 return pack(self.enum, typeEnumeration)
49 def IsEnum(x):
50 return isinstance(x, Enum)
52 def mkenum(enum):
53 if IsEnum(enum): return enum
54 return Enum(enum)
56 # Jack changed the way this is done
57 class InsertionLoc:
58 def __init__(self, of, pos):
59 self.of = of
60 self.pos = pos
62 def __repr__(self):
63 return "InsertionLoc(%s, %s)" % (`self.of`, `self.pos`)
65 def __aepack__(self):
66 rec = {'kobj': self.of, 'kpos': self.pos}
67 return pack(rec, forcetype='insl')
69 # Convenience functions for dsp:
70 def beginning(of):
71 return InsertionLoc(of, Enum('bgng'))
73 def end(of):
74 return InsertionLoc(of, Enum('end '))
76 class Boolean:
77 """An AE boolean value"""
79 def __init__(self, bool):
80 self.bool = (not not bool)
82 def __repr__(self):
83 return "Boolean(%s)" % `self.bool`
85 def __str__(self):
86 if self.bool:
87 return "True"
88 else:
89 return "False"
91 def __aepack__(self):
92 return pack(struct.pack('b', self.bool), 'bool')
94 def IsBoolean(x):
95 return isinstance(x, Boolean)
97 def mkboolean(bool):
98 if IsBoolean(bool): return bool
99 return Boolean(bool)
101 class Type:
102 """An AE 4-char typename object"""
104 def __init__(self, type):
105 self.type = "%-4.4s" % str(type)
107 def __repr__(self):
108 return "Type(%s)" % `self.type`
110 def __str__(self):
111 return string.strip(self.type)
113 def __aepack__(self):
114 return pack(self.type, typeType)
116 def IsType(x):
117 return isinstance(x, Type)
119 def mktype(type):
120 if IsType(type): return type
121 return Type(type)
124 class Keyword:
125 """An AE 4-char keyword object"""
127 def __init__(self, keyword):
128 self.keyword = "%-4.4s" % str(keyword)
130 def __repr__(self):
131 return "Keyword(%s)" % `self.keyword`
133 def __str__(self):
134 return string.strip(self.keyword)
136 def __aepack__(self):
137 return pack(self.keyword, typeKeyword)
139 def IsKeyword(x):
140 return isinstance(x, Keyword)
142 class Range:
143 """An AE range object"""
145 def __init__(self, start, stop):
146 self.start = start
147 self.stop = stop
149 def __repr__(self):
150 return "Range(%s, %s)" % (`self.start`, `self.stop`)
152 def __str__(self):
153 return "%s thru %s" % (nice(self.start), nice(self.stop))
155 def __aepack__(self):
156 return pack({'star': self.start, 'stop': self.stop}, 'rang')
158 def IsRange(x):
159 return isinstance(x, Range)
161 class Comparison:
162 """An AE Comparison"""
164 def __init__(self, obj1, relo, obj2):
165 self.obj1 = obj1
166 self.relo = "%-4.4s" % str(relo)
167 self.obj2 = obj2
169 def __repr__(self):
170 return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
172 def __str__(self):
173 return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
175 def __aepack__(self):
176 return pack({'obj1': self.obj1,
177 'relo': mkenum(self.relo),
178 'obj2': self.obj2},
179 'cmpd')
181 def IsComparison(x):
182 return isinstance(x, Comparison)
184 class NComparison(Comparison):
185 # The class attribute 'relo' must be set in a subclass
187 def __init__(self, obj1, obj2):
188 Comparison.__init__(obj1, self.relo, obj2)
190 class Ordinal:
191 """An AE Ordinal"""
193 def __init__(self, abso):
194 # self.obj1 = obj1
195 self.abso = "%-4.4s" % str(abso)
197 def __repr__(self):
198 return "Ordinal(%s)" % (`self.abso`)
200 def __str__(self):
201 return "%s" % (string.strip(self.abso))
203 def __aepack__(self):
204 return pack(self.abso, 'abso')
206 def IsOrdinal(x):
207 return isinstance(x, Ordinal)
209 class NOrdinal(Ordinal):
210 # The class attribute 'abso' must be set in a subclass
212 def __init__(self):
213 Ordinal.__init__(self, self.abso)
215 class Logical:
216 """An AE logical expression object"""
218 def __init__(self, logc, term):
219 self.logc = "%-4.4s" % str(logc)
220 self.term = term
222 def __repr__(self):
223 return "Logical(%s, %s)" % (`self.logc`, `self.term`)
225 def __str__(self):
226 if type(self.term) == ListType and len(self.term) == 2:
227 return "%s %s %s" % (nice(self.term[0]),
228 string.strip(self.logc),
229 nice(self.term[1]))
230 else:
231 return "%s(%s)" % (string.strip(self.logc), nice(self.term))
233 def __aepack__(self):
234 return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
236 def IsLogical(x):
237 return isinstance(x, Logical)
239 class StyledText:
240 """An AE object respresenting text in a certain style"""
242 def __init__(self, style, text):
243 self.style = style
244 self.text = text
246 def __repr__(self):
247 return "StyledText(%s, %s)" % (`self.style`, `self.text`)
249 def __str__(self):
250 return self.text
252 def __aepack__(self):
253 return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
255 def IsStyledText(x):
256 return isinstance(x, StyledText)
258 class AEText:
259 """An AE text object with style, script and language specified"""
261 def __init__(self, script, style, text):
262 self.script = script
263 self.style = style
264 self.text = text
266 def __repr__(self):
267 return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
269 def __str__(self):
270 return self.text
272 def __aepack__(self):
273 return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
274 keyAEText: self.text}, typeAEText)
276 def IsAEText(x):
277 return isinstance(x, AEText)
279 class IntlText:
280 """A text object with script and language specified"""
282 def __init__(self, script, language, text):
283 self.script = script
284 self.language = language
285 self.text = text
287 def __repr__(self):
288 return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
290 def __str__(self):
291 return self.text
293 def __aepack__(self):
294 return pack(struct.pack('hh', self.script, self.language)+self.text,
295 typeIntlText)
297 def IsIntlText(x):
298 return isinstance(x, IntlText)
300 class IntlWritingCode:
301 """An object representing script and language"""
303 def __init__(self, script, language):
304 self.script = script
305 self.language = language
307 def __repr__(self):
308 return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
310 def __str__(self):
311 return "script system %d, language %d"%(self.script, self.language)
313 def __aepack__(self):
314 return pack(struct.pack('hh', self.script, self.language),
315 typeIntlWritingCode)
317 def IsIntlWritingCode(x):
318 return isinstance(x, IntlWritingCode)
320 class QDPoint:
321 """A point"""
323 def __init__(self, v, h):
324 self.v = v
325 self.h = h
327 def __repr__(self):
328 return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
330 def __str__(self):
331 return "(%d, %d)"%(self.v, self.h)
333 def __aepack__(self):
334 return pack(struct.pack('hh', self.v, self.h),
335 typeQDPoint)
337 def IsQDPoint(x):
338 return isinstance(x, QDPoint)
340 class QDRectangle:
341 """A rectangle"""
343 def __init__(self, v0, h0, v1, h1):
344 self.v0 = v0
345 self.h0 = h0
346 self.v1 = v1
347 self.h1 = h1
349 def __repr__(self):
350 return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
351 `self.v1`, `self.h1`)
353 def __str__(self):
354 return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
356 def __aepack__(self):
357 return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
358 typeQDRectangle)
360 def IsQDRectangle(x):
361 return isinstance(x, QDRectangle)
363 class RGBColor:
364 """An RGB color"""
366 def __init__(self, r, g, b):
367 self.r = r
368 self.g = g
369 self.b = b
371 def __repr__(self):
372 return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
374 def __str__(self):
375 return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
377 def __aepack__(self):
378 return pack(struct.pack('hhh', self.r, self.g, self.b),
379 typeRGBColor)
381 def IsRGBColor(x):
382 return isinstance(x, RGBColor)
384 class ObjectSpecifier:
386 """A class for constructing and manipulation AE object specifiers in python.
388 An object specifier is actually a record with four fields:
390 key type description
391 --- ---- -----------
393 'want' type 4-char class code of thing we want,
394 e.g. word, paragraph or property
396 'form' enum how we specify which 'want' thing(s) we want,
397 e.g. by index, by range, by name, or by property specifier
399 'seld' any which thing(s) we want,
400 e.g. its index, its name, or its property specifier
402 'from' object the object in which it is contained,
403 or null, meaning look for it in the application
405 Note that we don't call this class plain "Object", since that name
406 is likely to be used by the application.
409 def __init__(self, want, form, seld, fr = None):
410 self.want = want
411 self.form = form
412 self.seld = seld
413 self.fr = fr
415 def __repr__(self):
416 s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
417 if self.fr:
418 s = s + ", %s)" % `self.fr`
419 else:
420 s = s + ")"
421 return s
423 def __aepack__(self):
424 return pack({'want': mktype(self.want),
425 'form': mkenum(self.form),
426 'seld': self.seld,
427 'from': self.fr},
428 'obj ')
430 def IsObjectSpecifier(x):
431 return isinstance(x, ObjectSpecifier)
434 # Backwards compatability, sigh...
435 class Property(ObjectSpecifier):
437 def __init__(self, which, fr = None, want='prop'):
438 ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
440 def __repr__(self):
441 if self.fr:
442 return "Property(%s, %s)" % (`self.seld.type`, `self.fr`)
443 else:
444 return "Property(%s)" % `self.seld.type`
446 def __str__(self):
447 if self.fr:
448 return "Property %s of %s" % (str(self.seld), str(self.fr))
449 else:
450 return "Property %s" % str(self.seld)
453 class NProperty(ObjectSpecifier):
454 # Subclasses *must* self baseclass attributes:
455 # want is the type of this property
456 # which is the property name of this property
458 def __init__(self, fr = None):
459 #try:
460 # dummy = self.want
461 #except:
462 # self.want = 'prop'
463 self.want = 'prop'
464 ObjectSpecifier.__init__(self, self.want, 'prop',
465 mktype(self.which), fr)
467 def __repr__(self):
468 rv = "Property(%s"%`self.seld.type`
469 if self.fr:
470 rv = rv + ", fr=%s" % `self.fr`
471 if self.want != 'prop':
472 rv = rv + ", want=%s" % `self.want`
473 return rv + ")"
475 def __str__(self):
476 if self.fr:
477 return "Property %s of %s" % (str(self.seld), str(self.fr))
478 else:
479 return "Property %s" % str(self.seld)
482 class SelectableItem(ObjectSpecifier):
484 def __init__(self, want, seld, fr = None):
485 t = type(seld)
486 if t == StringType:
487 form = 'name'
488 elif IsRange(seld):
489 form = 'rang'
490 elif IsComparison(seld) or IsLogical(seld):
491 form = 'test'
492 elif t == TupleType:
493 # Breakout: specify both form and seld in a tuple
494 # (if you want ID or rele or somesuch)
495 form, seld = seld
496 else:
497 form = 'indx'
498 ObjectSpecifier.__init__(self, want, form, seld, fr)
501 class ComponentItem(SelectableItem):
502 # Derived classes *must* set the *class attribute* 'want' to some constant
503 # Also, dictionaries _propdict and _elemdict must be set to map property
504 # and element names to the correct classes
506 _propdict = {}
507 _elemdict = {}
508 def __init__(self, which, fr = None):
509 SelectableItem.__init__(self, self.want, which, fr)
511 def __repr__(self):
512 if not self.fr:
513 return "%s(%s)" % (self.__class__.__name__, `self.seld`)
514 return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
516 def __str__(self):
517 seld = self.seld
518 if type(seld) == StringType:
519 ss = repr(seld)
520 elif IsRange(seld):
521 start, stop = seld.start, seld.stop
522 if type(start) == InstanceType == type(stop) and \
523 start.__class__ == self.__class__ == stop.__class__:
524 ss = str(start.seld) + " thru " + str(stop.seld)
525 else:
526 ss = str(seld)
527 else:
528 ss = str(seld)
529 s = "%s %s" % (self.__class__.__name__, ss)
530 if self.fr: s = s + " of %s" % str(self.fr)
531 return s
533 def __getattr__(self, name):
534 if self._elemdict.has_key(name):
535 cls = self._elemdict[name]
536 return DelayedComponentItem(cls, self)
537 if self._propdict.has_key(name):
538 cls = self._propdict[name]
539 return cls(self)
540 raise AttributeError, name
543 class DelayedComponentItem:
544 def __init__(self, compclass, fr):
545 self.compclass = compclass
546 self.fr = fr
548 def __call__(self, which):
549 return self.compclass(which, self.fr)
551 def __repr__(self):
552 return "%s(???, %s)" % (self.__class__.__name__, `self.fr`)
554 def __str__(self):
555 return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
557 template = """
558 class %s(ComponentItem): want = '%s'
561 exec template % ("Text", 'text')
562 exec template % ("Character", 'cha ')
563 exec template % ("Word", 'cwor')
564 exec template % ("Line", 'clin')
565 exec template % ("paragraph", 'cpar')
566 exec template % ("Window", 'cwin')
567 exec template % ("Document", 'docu')
568 exec template % ("File", 'file')
569 exec template % ("InsertionPoint", 'cins')