aetypes.py 14.6 KB
Newer Older
1 2
"""aetypes - Python objects representing various AE types."""

3
from Carbon.AppleEvents import *
4 5 6 7 8 9 10 11
import struct
from types import *
import string

#
# convoluted, since there are cyclic dependencies between this file and
# aetools_convert.
#
12
def pack(*args, **kwargs):
Jack Jansen's avatar
Jack Jansen committed
13 14
    from aepack import pack
    return pack( *args, **kwargs)
15

16
def nice(s):
Jack Jansen's avatar
Jack Jansen committed
17 18 19
    """'nice' representation of an object"""
    if type(s) is StringType: return repr(s)
    else: return str(s)
20 21

class Unknown:
Jack Jansen's avatar
Jack Jansen committed
22
    """An uninterpreted AE object"""
23

Jack Jansen's avatar
Jack Jansen committed
24 25 26
    def __init__(self, type, data):
        self.type = type
        self.data = data
27

Jack Jansen's avatar
Jack Jansen committed
28
    def __repr__(self):
29
        return "Unknown(%r, %r)" % (self.type, self.data)
30

Jack Jansen's avatar
Jack Jansen committed
31 32
    def __aepack__(self):
        return pack(self.data, self.type)
33 34

class Enum:
Jack Jansen's avatar
Jack Jansen committed
35
    """An AE enumeration value"""
36

Jack Jansen's avatar
Jack Jansen committed
37 38
    def __init__(self, enum):
        self.enum = "%-4.4s" % str(enum)
39

Jack Jansen's avatar
Jack Jansen committed
40
    def __repr__(self):
41
        return "Enum(%r)" % (self.enum,)
42

Jack Jansen's avatar
Jack Jansen committed
43 44
    def __str__(self):
        return string.strip(self.enum)
45

Jack Jansen's avatar
Jack Jansen committed
46 47
    def __aepack__(self):
        return pack(self.enum, typeEnumeration)
48 49

def IsEnum(x):
Jack Jansen's avatar
Jack Jansen committed
50
    return isinstance(x, Enum)
51 52

def mkenum(enum):
Jack Jansen's avatar
Jack Jansen committed
53 54
    if IsEnum(enum): return enum
    return Enum(enum)
55

56 57
# Jack changed the way this is done
class InsertionLoc:
Jack Jansen's avatar
Jack Jansen committed
58 59 60
    def __init__(self, of, pos):
        self.of = of
        self.pos = pos
61

Jack Jansen's avatar
Jack Jansen committed
62
    def __repr__(self):
63
        return "InsertionLoc(%r, %r)" % (self.of, self.pos)
64

Jack Jansen's avatar
Jack Jansen committed
65 66 67
    def __aepack__(self):
        rec = {'kobj': self.of, 'kpos': self.pos}
        return pack(rec, forcetype='insl')
68

69 70
# Convenience functions for dsp:
def beginning(of):
Jack Jansen's avatar
Jack Jansen committed
71
    return InsertionLoc(of, Enum('bgng'))
72

73
def end(of):
Jack Jansen's avatar
Jack Jansen committed
74
    return InsertionLoc(of, Enum('end '))
75

76
class Boolean:
Jack Jansen's avatar
Jack Jansen committed
77
    """An AE boolean value"""
78

Jack Jansen's avatar
Jack Jansen committed
79 80
    def __init__(self, bool):
        self.bool = (not not bool)
81

Jack Jansen's avatar
Jack Jansen committed
82
    def __repr__(self):
83
        return "Boolean(%r)" % (self.bool,)
84

Jack Jansen's avatar
Jack Jansen committed
85 86 87 88 89
    def __str__(self):
        if self.bool:
            return "True"
        else:
            return "False"
90

Jack Jansen's avatar
Jack Jansen committed
91 92
    def __aepack__(self):
        return pack(struct.pack('b', self.bool), 'bool')
93 94

def IsBoolean(x):
Jack Jansen's avatar
Jack Jansen committed
95
    return isinstance(x, Boolean)
96 97

def mkboolean(bool):
Jack Jansen's avatar
Jack Jansen committed
98 99
    if IsBoolean(bool): return bool
    return Boolean(bool)
100 101

class Type:
Jack Jansen's avatar
Jack Jansen committed
102
    """An AE 4-char typename object"""
103

Jack Jansen's avatar
Jack Jansen committed
104 105
    def __init__(self, type):
        self.type = "%-4.4s" % str(type)
106

Jack Jansen's avatar
Jack Jansen committed
107
    def __repr__(self):
108
        return "Type(%r)" % (self.type,)
109

Jack Jansen's avatar
Jack Jansen committed
110 111
    def __str__(self):
        return string.strip(self.type)
112

Jack Jansen's avatar
Jack Jansen committed
113 114
    def __aepack__(self):
        return pack(self.type, typeType)
115 116

def IsType(x):
Jack Jansen's avatar
Jack Jansen committed
117
    return isinstance(x, Type)
118 119

def mktype(type):
Jack Jansen's avatar
Jack Jansen committed
120 121
    if IsType(type): return type
    return Type(type)
122 123 124


class Keyword:
Jack Jansen's avatar
Jack Jansen committed
125
    """An AE 4-char keyword object"""
126

Jack Jansen's avatar
Jack Jansen committed
127 128
    def __init__(self, keyword):
        self.keyword = "%-4.4s" % str(keyword)
129

Jack Jansen's avatar
Jack Jansen committed
130
    def __repr__(self):
131
        return "Keyword(%r)" % `self.keyword`
132

Jack Jansen's avatar
Jack Jansen committed
133 134
    def __str__(self):
        return string.strip(self.keyword)
135

Jack Jansen's avatar
Jack Jansen committed
136 137
    def __aepack__(self):
        return pack(self.keyword, typeKeyword)
138 139

def IsKeyword(x):
Jack Jansen's avatar
Jack Jansen committed
140
    return isinstance(x, Keyword)
141 142

class Range:
Jack Jansen's avatar
Jack Jansen committed
143
    """An AE range object"""
144

Jack Jansen's avatar
Jack Jansen committed
145 146 147
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop
148

Jack Jansen's avatar
Jack Jansen committed
149
    def __repr__(self):
150
        return "Range(%r, %r)" % (self.start, self.stop)
151

Jack Jansen's avatar
Jack Jansen committed
152 153
    def __str__(self):
        return "%s thru %s" % (nice(self.start), nice(self.stop))
154

Jack Jansen's avatar
Jack Jansen committed
155 156
    def __aepack__(self):
        return pack({'star': self.start, 'stop': self.stop}, 'rang')
157 158

def IsRange(x):
Jack Jansen's avatar
Jack Jansen committed
159
    return isinstance(x, Range)
160 161

class Comparison:
Jack Jansen's avatar
Jack Jansen committed
162
    """An AE Comparison"""
163

Jack Jansen's avatar
Jack Jansen committed
164 165 166 167
    def __init__(self, obj1, relo, obj2):
        self.obj1 = obj1
        self.relo = "%-4.4s" % str(relo)
        self.obj2 = obj2
168

Jack Jansen's avatar
Jack Jansen committed
169
    def __repr__(self):
170
        return "Comparison(%r, %r, %r)" % (self.obj1, self.relo, self.obj2)
171

Jack Jansen's avatar
Jack Jansen committed
172 173
    def __str__(self):
        return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
174

Jack Jansen's avatar
Jack Jansen committed
175 176 177 178 179
    def __aepack__(self):
        return pack({'obj1': self.obj1,
                 'relo': mkenum(self.relo),
                 'obj2': self.obj2},
                'cmpd')
180 181

def IsComparison(x):
Jack Jansen's avatar
Jack Jansen committed
182
    return isinstance(x, Comparison)
183

184
class NComparison(Comparison):
Jack Jansen's avatar
Jack Jansen committed
185
    # The class attribute 'relo' must be set in a subclass
186

Jack Jansen's avatar
Jack Jansen committed
187 188
    def __init__(self, obj1, obj2):
        Comparison.__init__(obj1, self.relo, obj2)
189 190

class Ordinal:
Jack Jansen's avatar
Jack Jansen committed
191
    """An AE Ordinal"""
192

Jack Jansen's avatar
Jack Jansen committed
193 194 195
    def __init__(self, abso):
#       self.obj1 = obj1
        self.abso = "%-4.4s" % str(abso)
196

Jack Jansen's avatar
Jack Jansen committed
197
    def __repr__(self):
198
        return "Ordinal(%r)" % (self.abso,)
199

Jack Jansen's avatar
Jack Jansen committed
200 201
    def __str__(self):
        return "%s" % (string.strip(self.abso))
202

Jack Jansen's avatar
Jack Jansen committed
203 204
    def __aepack__(self):
        return pack(self.abso, 'abso')
205 206

def IsOrdinal(x):
Jack Jansen's avatar
Jack Jansen committed
207
    return isinstance(x, Ordinal)
208

209
class NOrdinal(Ordinal):
Jack Jansen's avatar
Jack Jansen committed
210
    # The class attribute 'abso' must be set in a subclass
211

Jack Jansen's avatar
Jack Jansen committed
212 213
    def __init__(self):
        Ordinal.__init__(self, self.abso)
214 215

class Logical:
Jack Jansen's avatar
Jack Jansen committed
216
    """An AE logical expression object"""
217

Jack Jansen's avatar
Jack Jansen committed
218 219 220
    def __init__(self, logc, term):
        self.logc = "%-4.4s" % str(logc)
        self.term = term
221

Jack Jansen's avatar
Jack Jansen committed
222
    def __repr__(self):
223
        return "Logical(%r, %r)" % (self.logc, self.term)
224

Jack Jansen's avatar
Jack Jansen committed
225 226 227 228 229 230 231
    def __str__(self):
        if type(self.term) == ListType and len(self.term) == 2:
            return "%s %s %s" % (nice(self.term[0]),
                                 string.strip(self.logc),
                                 nice(self.term[1]))
        else:
            return "%s(%s)" % (string.strip(self.logc), nice(self.term))
232

Jack Jansen's avatar
Jack Jansen committed
233 234
    def __aepack__(self):
        return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
235 236

def IsLogical(x):
Jack Jansen's avatar
Jack Jansen committed
237
    return isinstance(x, Logical)
238 239

class StyledText:
Jack Jansen's avatar
Jack Jansen committed
240
    """An AE object respresenting text in a certain style"""
241

Jack Jansen's avatar
Jack Jansen committed
242 243 244
    def __init__(self, style, text):
        self.style = style
        self.text = text
245

Jack Jansen's avatar
Jack Jansen committed
246
    def __repr__(self):
247
        return "StyledText(%r, %r)" % (self.style, self.text)
248

Jack Jansen's avatar
Jack Jansen committed
249 250
    def __str__(self):
        return self.text
251

Jack Jansen's avatar
Jack Jansen committed
252 253
    def __aepack__(self):
        return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
254 255

def IsStyledText(x):
Jack Jansen's avatar
Jack Jansen committed
256
    return isinstance(x, StyledText)
257 258

class AEText:
Jack Jansen's avatar
Jack Jansen committed
259
    """An AE text object with style, script and language specified"""
260

Jack Jansen's avatar
Jack Jansen committed
261 262 263 264
    def __init__(self, script, style, text):
        self.script = script
        self.style = style
        self.text = text
265

Jack Jansen's avatar
Jack Jansen committed
266
    def __repr__(self):
267
        return "AEText(%r, %r, %r)" % (self.script, self.style, self.text)
268

Jack Jansen's avatar
Jack Jansen committed
269 270
    def __str__(self):
        return self.text
271

Jack Jansen's avatar
Jack Jansen committed
272 273 274
    def __aepack__(self):
        return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
                 keyAEText: self.text}, typeAEText)
275 276

def IsAEText(x):
Jack Jansen's avatar
Jack Jansen committed
277
    return isinstance(x, AEText)
278 279

class IntlText:
Jack Jansen's avatar
Jack Jansen committed
280
    """A text object with script and language specified"""
281

Jack Jansen's avatar
Jack Jansen committed
282 283 284 285
    def __init__(self, script, language, text):
        self.script = script
        self.language = language
        self.text = text
286

Jack Jansen's avatar
Jack Jansen committed
287
    def __repr__(self):
288
        return "IntlText(%r, %r, %r)" % (self.script, self.language, self.text)
289

Jack Jansen's avatar
Jack Jansen committed
290 291
    def __str__(self):
        return self.text
292

Jack Jansen's avatar
Jack Jansen committed
293 294 295
    def __aepack__(self):
        return pack(struct.pack('hh', self.script, self.language)+self.text,
            typeIntlText)
296 297

def IsIntlText(x):
Jack Jansen's avatar
Jack Jansen committed
298
    return isinstance(x, IntlText)
299 300

class IntlWritingCode:
Jack Jansen's avatar
Jack Jansen committed
301
    """An object representing script and language"""
302

Jack Jansen's avatar
Jack Jansen committed
303 304 305
    def __init__(self, script, language):
        self.script = script
        self.language = language
306

Jack Jansen's avatar
Jack Jansen committed
307
    def __repr__(self):
308
        return "IntlWritingCode(%r, %r)" % (self.script, self.language)
309

Jack Jansen's avatar
Jack Jansen committed
310 311
    def __str__(self):
        return "script system %d, language %d"%(self.script, self.language)
312

Jack Jansen's avatar
Jack Jansen committed
313 314 315
    def __aepack__(self):
        return pack(struct.pack('hh', self.script, self.language),
            typeIntlWritingCode)
316 317

def IsIntlWritingCode(x):
Jack Jansen's avatar
Jack Jansen committed
318
    return isinstance(x, IntlWritingCode)
319 320

class QDPoint:
Jack Jansen's avatar
Jack Jansen committed
321
    """A point"""
322

Jack Jansen's avatar
Jack Jansen committed
323 324 325
    def __init__(self, v, h):
        self.v = v
        self.h = h
326

Jack Jansen's avatar
Jack Jansen committed
327
    def __repr__(self):
328
        return "QDPoint(%r, %r)" % (self.v, self.h)
329

Jack Jansen's avatar
Jack Jansen committed
330 331
    def __str__(self):
        return "(%d, %d)"%(self.v, self.h)
332

Jack Jansen's avatar
Jack Jansen committed
333 334 335
    def __aepack__(self):
        return pack(struct.pack('hh', self.v, self.h),
            typeQDPoint)
336 337

def IsQDPoint(x):
Jack Jansen's avatar
Jack Jansen committed
338
    return isinstance(x, QDPoint)
339 340

class QDRectangle:
Jack Jansen's avatar
Jack Jansen committed
341
    """A rectangle"""
342

Jack Jansen's avatar
Jack Jansen committed
343 344 345 346 347
    def __init__(self, v0, h0, v1, h1):
        self.v0 = v0
        self.h0 = h0
        self.v1 = v1
        self.h1 = h1
348

Jack Jansen's avatar
Jack Jansen committed
349
    def __repr__(self):
350
        return "QDRectangle(%r, %r, %r, %r)" % (self.v0, self.h0, self.v1, self.h1)
351

Jack Jansen's avatar
Jack Jansen committed
352 353
    def __str__(self):
        return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
354

Jack Jansen's avatar
Jack Jansen committed
355 356 357
    def __aepack__(self):
        return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
            typeQDRectangle)
358 359

def IsQDRectangle(x):
Jack Jansen's avatar
Jack Jansen committed
360
    return isinstance(x, QDRectangle)
361 362

class RGBColor:
Jack Jansen's avatar
Jack Jansen committed
363
    """An RGB color"""
364

Jack Jansen's avatar
Jack Jansen committed
365 366 367 368
    def __init__(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b
369

Jack Jansen's avatar
Jack Jansen committed
370
    def __repr__(self):
371
        return "RGBColor(%r, %r, %r)" % (self.r, self.g, self.b)
372

Jack Jansen's avatar
Jack Jansen committed
373 374
    def __str__(self):
        return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
375

Jack Jansen's avatar
Jack Jansen committed
376 377 378
    def __aepack__(self):
        return pack(struct.pack('hhh', self.r, self.g, self.b),
            typeRGBColor)
379 380

def IsRGBColor(x):
Jack Jansen's avatar
Jack Jansen committed
381
    return isinstance(x, RGBColor)
382 383

class ObjectSpecifier:
384

Jack Jansen's avatar
Jack Jansen committed
385
    """A class for constructing and manipulation AE object specifiers in python.
386

Jack Jansen's avatar
Jack Jansen committed
387
    An object specifier is actually a record with four fields:
388

Jack Jansen's avatar
Jack Jansen committed
389 390
    key type    description
    --- ----    -----------
391

Jack Jansen's avatar
Jack Jansen committed
392 393
    'want'  type    4-char class code of thing we want,
            e.g. word, paragraph or property
394

Jack Jansen's avatar
Jack Jansen committed
395 396
    'form'  enum    how we specify which 'want' thing(s) we want,
            e.g. by index, by range, by name, or by property specifier
397

Jack Jansen's avatar
Jack Jansen committed
398 399
    'seld'  any which thing(s) we want,
            e.g. its index, its name, or its property specifier
400

Jack Jansen's avatar
Jack Jansen committed
401 402
    'from'  object  the object in which it is contained,
            or null, meaning look for it in the application
403

Jack Jansen's avatar
Jack Jansen committed
404 405 406
    Note that we don't call this class plain "Object", since that name
    is likely to be used by the application.
    """
407

Jack Jansen's avatar
Jack Jansen committed
408 409 410 411 412
    def __init__(self, want, form, seld, fr = None):
        self.want = want
        self.form = form
        self.seld = seld
        self.fr = fr
413

Jack Jansen's avatar
Jack Jansen committed
414
    def __repr__(self):
415
        s = "ObjectSpecifier(%r, %r, %r" % (self.want, self.form, self.seld)
Jack Jansen's avatar
Jack Jansen committed
416
        if self.fr:
417
            s = s + ", %r)" % (self.fr,)
Jack Jansen's avatar
Jack Jansen committed
418 419 420
        else:
            s = s + ")"
        return s
421

Jack Jansen's avatar
Jack Jansen committed
422 423 424 425 426 427
    def __aepack__(self):
        return pack({'want': mktype(self.want),
                 'form': mkenum(self.form),
                 'seld': self.seld,
                 'from': self.fr},
                'obj ')
428 429

def IsObjectSpecifier(x):
Jack Jansen's avatar
Jack Jansen committed
430
    return isinstance(x, ObjectSpecifier)
431 432 433 434 435


# Backwards compatability, sigh...
class Property(ObjectSpecifier):

Jack Jansen's avatar
Jack Jansen committed
436 437
    def __init__(self, which, fr = None, want='prop'):
        ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
438

Jack Jansen's avatar
Jack Jansen committed
439 440
    def __repr__(self):
        if self.fr:
441
            return "Property(%r, %r)" % (self.seld.type, self.fr)
Jack Jansen's avatar
Jack Jansen committed
442
        else:
443
            return "Property(%r)" % (self.seld.type,)
444

Jack Jansen's avatar
Jack Jansen committed
445 446 447 448 449
    def __str__(self):
        if self.fr:
            return "Property %s of %s" % (str(self.seld), str(self.fr))
        else:
            return "Property %s" % str(self.seld)
450 451 452


class NProperty(ObjectSpecifier):
Jack Jansen's avatar
Jack Jansen committed
453 454 455 456 457 458 459 460 461 462
    # Subclasses *must* self baseclass attributes:
    # want is the type of this property
    # which is the property name of this property

    def __init__(self, fr = None):
        #try:
        #   dummy = self.want
        #except:
        #   self.want = 'prop'
        self.want = 'prop'
463
        ObjectSpecifier.__init__(self, self.want, 'prop',
Jack Jansen's avatar
Jack Jansen committed
464 465 466
                    mktype(self.which), fr)

    def __repr__(self):
467
        rv = "Property(%r" % (self.seld.type,)
Jack Jansen's avatar
Jack Jansen committed
468
        if self.fr:
469
            rv = rv + ", fr=%r" % (self.fr,)
Jack Jansen's avatar
Jack Jansen committed
470
        if self.want != 'prop':
471
            rv = rv + ", want=%r" % (self.want,)
Jack Jansen's avatar
Jack Jansen committed
472
        return rv + ")"
473

Jack Jansen's avatar
Jack Jansen committed
474 475 476 477 478
    def __str__(self):
        if self.fr:
            return "Property %s of %s" % (str(self.seld), str(self.fr))
        else:
            return "Property %s" % str(self.seld)
479 480 481


class SelectableItem(ObjectSpecifier):
482

Jack Jansen's avatar
Jack Jansen committed
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
    def __init__(self, want, seld, fr = None):
        t = type(seld)
        if t == StringType:
            form = 'name'
        elif IsRange(seld):
            form = 'rang'
        elif IsComparison(seld) or IsLogical(seld):
            form = 'test'
        elif t == TupleType:
            # Breakout: specify both form and seld in a tuple
            # (if you want ID or rele or somesuch)
            form, seld = seld
        else:
            form = 'indx'
        ObjectSpecifier.__init__(self, want, form, seld, fr)
498 499 500


class ComponentItem(SelectableItem):
Jack Jansen's avatar
Jack Jansen committed
501 502 503 504 505 506 507 508
    # Derived classes *must* set the *class attribute* 'want' to some constant
    # Also, dictionaries _propdict and _elemdict must be set to map property
    # and element names to the correct classes

    _propdict = {}
    _elemdict = {}
    def __init__(self, which, fr = None):
        SelectableItem.__init__(self, self.want, which, fr)
509

Jack Jansen's avatar
Jack Jansen committed
510 511
    def __repr__(self):
        if not self.fr:
512 513
            return "%s(%r)" % (self.__class__.__name__, self.seld)
        return "%s(%r, %r)" % (self.__class__.__name__, self.seld, self.fr)
514

Jack Jansen's avatar
Jack Jansen committed
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
    def __str__(self):
        seld = self.seld
        if type(seld) == StringType:
            ss = repr(seld)
        elif IsRange(seld):
            start, stop = seld.start, seld.stop
            if type(start) == InstanceType == type(stop) and \
               start.__class__ == self.__class__ == stop.__class__:
                ss = str(start.seld) + " thru " + str(stop.seld)
            else:
                ss = str(seld)
        else:
            ss = str(seld)
        s = "%s %s" % (self.__class__.__name__, ss)
        if self.fr: s = s + " of %s" % str(self.fr)
        return s
531

Jack Jansen's avatar
Jack Jansen committed
532 533 534 535 536 537 538 539
    def __getattr__(self, name):
        if self._elemdict.has_key(name):
            cls = self._elemdict[name]
            return DelayedComponentItem(cls, self)
        if self._propdict.has_key(name):
            cls = self._propdict[name]
            return cls(self)
        raise AttributeError, name
540 541


542
class DelayedComponentItem:
Jack Jansen's avatar
Jack Jansen committed
543 544 545
    def __init__(self, compclass, fr):
        self.compclass = compclass
        self.fr = fr
546

Jack Jansen's avatar
Jack Jansen committed
547 548
    def __call__(self, which):
        return self.compclass(which, self.fr)
549

Jack Jansen's avatar
Jack Jansen committed
550
    def __repr__(self):
551
        return "%s(???, %r)" % (self.__class__.__name__, self.fr)
552

Jack Jansen's avatar
Jack Jansen committed
553 554
    def __str__(self):
        return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
555 556 557 558 559 560 561 562 563 564 565 566 567 568

template = """
class %s(ComponentItem): want = '%s'
"""

exec template % ("Text", 'text')
exec template % ("Character", 'cha ')
exec template % ("Word", 'cwor')
exec template % ("Line", 'clin')
exec template % ("paragraph", 'cpar')
exec template % ("Window", 'cwin')
exec template % ("Document", 'docu')
exec template % ("File", 'file')
exec template % ("InsertionPoint", 'cins')