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