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