1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | Lib/plat-mac/MiniAEFrame.py
"""MiniAEFrame - A minimal AppleEvent Application framework. There are two classes: AEServer -- a mixin class offering nice AE handling. MiniApplication -- a very minimal alternative to FrameWork.py, only suitable for the simplest of AppleEvent servers. """ from warnings import warnpy3k warnpy3k("In 3.x, the MiniAEFrame module is removed.", stacklevel=2) import traceback import MacOS from Carbon import AE from Carbon.AppleEvents import * from Carbon import Evt from Carbon.Events import * from Carbon import Menu from Carbon import Win from Carbon.Windows import * from Carbon import Qd import aetools import EasyDialogs kHighLevelEvent = 23 # Not defined anywhere for Python yet? class MiniApplication: """A minimal FrameWork.Application-like class""" def __init__(self): self.quitting = 0 # Initialize menu self.appleid = 1 self.quitid = 2 Menu.ClearMenuBar() self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024") applemenu.AppendMenu("%s;(-" % self.getaboutmenutext()) if MacOS.runtimemodel == 'ppc': applemenu.AppendResMenu('DRVR') applemenu.InsertMenu(0) self.quitmenu = Menu.NewMenu(self.quitid, "File") self.quitmenu.AppendMenu("Quit") self.quitmenu.SetItemCmd(1, ord("Q")) self.quitmenu.InsertMenu(0) Menu.DrawMenuBar() def __del__(self): self.close() def close(self): pass def mainloop(self, mask = everyEvent, timeout = 60*60): while not self.quitting: self.dooneevent(mask, timeout) def _quit(self): self.quitting = 1 def dooneevent(self, mask = everyEvent, timeout = 60*60): got, event = Evt.WaitNextEvent(mask, timeout) if got: self.lowlevelhandler(event) def lowlevelhandler(self, event): what, message, when, where, modifiers = event h, v = where if what == kHighLevelEvent: msg = "High Level Event: %r %r" % (code(message), code(h | (v<<16))) try: AE.AEProcessAppleEvent(event) except AE.Error, err: print 'AE error: ', err print 'in', msg traceback.print_exc() return elif what == keyDown: c = chr(message & charCodeMask) if modifiers & cmdKey: if c == '.': raise KeyboardInterrupt, "Command-period" if c == 'q': if hasattr(MacOS, 'OutputSeen'): MacOS.OutputSeen() self.quitting = 1 return elif what == mouseDown: partcode, window = Win.FindWindow(where) if partcode == inMenuBar: result = Menu.MenuSelect(where) id = (result>>16) & 0xffff # Hi word item = result & 0xffff # Lo word if id == self.appleid: if item == 1: EasyDialogs.Message(self.getabouttext()) elif item > 1 and hasattr(Menu, 'OpenDeskAcc'): name = self.applemenu.GetMenuItemText(item) Menu.OpenDeskAcc(name) elif id == self.quitid and item == 1: if hasattr(MacOS, 'OutputSeen'): MacOS.OutputSeen() self.quitting = 1 Menu.HiliteMenu(0) return # Anything not handled is passed to Python/SIOUX if hasattr(MacOS, 'HandleEvent'): MacOS.HandleEvent(event) else: print "Unhandled event:", event def getabouttext(self): return self.__class__.__name__ def getaboutmenutext(self): return "About %s\311" % self.__class__.__name__ class AEServer: def __init__(self): self.ae_handlers = {} def installaehandler(self, classe, type, callback): AE.AEInstallEventHandler(classe, type, self.callback_wrapper) self.ae_handlers[(classe, type)] = callback def close(self): for classe, type in self.ae_handlers.keys(): AE.AERemoveEventHandler(classe, type) def callback_wrapper(self, _request, _reply): _parameters, _attributes = aetools.unpackevent(_request) _class = _attributes['evcl'].type _type = _attributes['evid'].type if (_class, _type) in self.ae_handlers: _function = self.ae_handlers[(_class, _type)] elif (_class, '****') in self.ae_handlers: _function = self.ae_handlers[(_class, '****')] elif ('****', '****') in self.ae_handlers: _function = self.ae_handlers[('****', '****')] else: raise 'Cannot happen: AE callback without handler', (_class, _type) # XXXX Do key-to-name mapping here _parameters['_attributes'] = _attributes _parameters['_class'] = _class _parameters['_type'] = _type if '----' in _parameters: _object = _parameters['----'] del _parameters['----'] # The try/except that used to be here can mask programmer errors. # Let the program crash, the programmer can always add a **args # to the formal parameter list. rv = _function(_object, **_parameters) else: #Same try/except comment as above rv = _function(**_parameters) if rv is None: aetools.packevent(_reply, {}) else: aetools.packevent(_reply, {'----':rv}) def code(x): "Convert a long int to the 4-character code it really is" s = '' for i in range(4): x, c = divmod(x, 256) s = chr(c) + s return s class _Test(AEServer, MiniApplication): """Mini test application, handles required events""" def __init__(self): MiniApplication.__init__(self) AEServer.__init__(self) self.installaehandler('aevt', 'oapp', self.open_app) self.installaehandler('aevt', 'quit', self.quit) self.installaehandler('****', '****', self.other) self.mainloop() def quit(self, **args): self._quit() def open_app(self, **args): pass def other(self, _object=None, _class=None, _type=None, **args): print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args if __name__ == '__main__': _Test() |