diff options
Diffstat (limited to 'Mac/scripts/EditPythonPrefs.py')
-rw-r--r-- | Mac/scripts/EditPythonPrefs.py | 402 |
1 files changed, 60 insertions, 342 deletions
diff --git a/Mac/scripts/EditPythonPrefs.py b/Mac/scripts/EditPythonPrefs.py index bc7e2da..d45a612 100644 --- a/Mac/scripts/EditPythonPrefs.py +++ b/Mac/scripts/EditPythonPrefs.py @@ -13,9 +13,8 @@ import MacOS import os import sys import Res # For Res.Error - -# Resource in the Python resource chain -PREFNAME_NAME="PythonPreferenceFileName" +import pythonprefs +import EasyDialogs # resource IDs in our own resources (dialogs, etc) MESSAGE_ID = 256 @@ -31,88 +30,46 @@ OPTIONS_ITEM = 7 # The options dialog. There is a correspondence between # the dialog item numbers and the option. OPT_DIALOG_ID = 510 -# 1 thru 9 are the options + +# Map dialog item numbers to option names (and the reverse) +opt_dialog_map = [ + None, + "inspect", + "verbose", + "optimize", + "unbuffered", + "debugging", + "keepopen", + "keeperror", + "nointopt", + "noargs", + "delayconsole"] +opt_dialog_dict = {} +for i in range(len(opt_dialog_map)): + if opt_dialog_map[i]: + opt_dialog_dict[opt_dialog_map[i]] = i +# 1 thru 10 are the options # The GUSI creator/type and delay-console -OD_CREATOR_ITEM = 10 -OD_TYPE_ITEM = 11 -OD_DELAYCONSOLE_ITEM = 12 +OD_CREATOR_ITEM = 11 +OD_TYPE_ITEM = 12 OD_OK_ITEM = 13 OD_CANCEL_ITEM = 14 -# Resource IDs in the preferences file -PATH_STRINGS_ID = 128 -DIRECTORY_ID = 128 -OPTIONS_ID = 128 -GUSI_ID = 10240 - -# Override IDs (in the applet) -OVERRIDE_PATH_STRINGS_ID = 129 -OVERRIDE_DIRECTORY_ID = 129 -OVERRIDE_OPTIONS_ID = 129 -OVERRIDE_GUSI_ID = 10241 - -# Things we know about the GUSI resource. Note the code knows these too. -GUSIPOS_TYPE=0 -GUSIPOS_CREATOR=4 -GUSIPOS_SKIP=8 -GUSIPOS_FLAGS=9 -GUSIPOS_VERSION=10 -GUSIVERSION='0181' -GUSIFLAGS_DELAY=0x20 # Mask - -READ = 1 -WRITE = 2 -smAllScripts = -3 -kOnSystemDisk = 0x8000 - -def restolist(data): - """Convert STR# resource data to a list of strings""" - if not data: - return [] - num, = struct.unpack('h', data[:2]) - data = data[2:] - rv = [] - for i in range(num): - strlen = ord(data[0]) - if strlen < 0: strlen = strlen + 256 - str = data[1:strlen+1] - data = data[strlen+1:] - rv.append(str) - return rv - -def listtores(list): - """Convert a list of strings to STR# resource data""" - rv = struct.pack('h', len(list)) - for str in list: - rv = rv + chr(len(str)) + str - return rv - -def message(str = "Hello, world!", id = MESSAGE_ID): - """Show a simple alert with a text message""" - d = GetNewDialog(id, -1) - d.SetDialogDefaultItem(1) - tp, h, rect = d.GetDialogItem(2) - SetDialogItemText(h, str) - while 1: - n = ModalDialog(None) - if n == 1: break - -def optinteract((options, creator, type, delaycons)): +def optinteract(options): """Let the user interact with the options dialog""" - old_options = (options[:], creator, type, delaycons) d = GetNewDialog(OPT_DIALOG_ID, -1) tp, h, rect = d.GetDialogItem(OD_CREATOR_ITEM) - SetDialogItemText(h, creator) + SetDialogItemText(h, options['creator']) tp, h, rect = d.GetDialogItem(OD_TYPE_ITEM) - SetDialogItemText(h, type) + SetDialogItemText(h, options['type']) d.SetDialogDefaultItem(OD_OK_ITEM) d.SetDialogCancelItem(OD_CANCEL_ITEM) + while 1: - for i in range(len(options)): - tp, h, rect = d.GetDialogItem(i+1) - h.as_Control().SetControlValue(options[i]) - tp, h, rect = d.GetDialogItem(OD_DELAYCONSOLE_ITEM) - h.as_Control().SetControlValue(delaycons) + for name in opt_dialog_dict.keys(): + num = opt_dialog_dict[name] + tp, h, rect = d.GetDialogItem(num) + h.as_Control().SetControlValue(options[name]) n = ModalDialog(None) if n == OD_OK_ITEM: tp, h, rect = d.GetDialogItem(OD_CREATOR_ITEM) @@ -120,25 +77,24 @@ def optinteract((options, creator, type, delaycons)): tp, h, rect = d.GetDialogItem(OD_TYPE_ITEM) ntype = GetDialogItemText(h) if len(ncreator) == 4 and len(ntype) == 4: - return options, ncreator, ntype, delaycons + options['creator'] = ncreator + options['type'] = ntype + return options else: - sys.stderr.write('\007') + MacOS.SysBeep() elif n == OD_CANCEL_ITEM: - return old_options + return elif n in (OD_CREATOR_ITEM, OD_TYPE_ITEM): pass - elif n == OD_DELAYCONSOLE_ITEM: - delaycons = (not delaycons) - elif 1 <= n <= len(options): - options[n-1] = (not options[n-1]) + elif 1 <= n <= len(opt_dialog_map): + options[opt_dialog_map[n]] = (not options[opt_dialog_map[n]]) -def interact(list, pythondir, options, title): +def interact(options, title): """Let the user interact with the dialog""" - opythondir = pythondir try: # Try to go to the "correct" dir for GetDirectory - os.chdir(pythondir.as_pathname()) + os.chdir(options['dir'].as_pathname()) except os.error: pass d = GetNewDialog(DIALOG_ID, -1) @@ -146,7 +102,7 @@ def interact(list, pythondir, options, title): SetDialogItemText(h, title) tp, h, rect = d.GetDialogItem(TEXT_ITEM) ## SetDialogItemText(h, string.joinfields(list, '\r')) - h.data = string.joinfields(list, '\r') + h.data = string.joinfields(options['path'], '\r') d.SelectDialogItemText(TEXT_ITEM, 0, 32767) d.SelectDialogItemText(TEXT_ITEM, 0, 0) ## d.SetDialogDefaultItem(OK_ITEM) @@ -164,272 +120,34 @@ def interact(list, pythondir, options, title): if n == DIR_ITEM: fss, ok = macfs.GetDirectory('Select python home folder:') if ok: - pythondir = fss + options['dir'] = fss if n == OPTIONS_ITEM: - options = optinteract(options) + noptions = options + for k in options.keys(): + noptions[k] = options[k] + noptions = optinteract(noptions) + if noptions: + options = noptions tmp = string.splitfields(h.data, '\r') - rv = [] + newpath = [] for i in tmp: if i: - rv.append(i) - return rv, pythondir, options - -def getprefpath(id): - # Load the path and directory resources - try: - sr = GetResource('STR#', id) - except (MacOS.Error, Res.Error): - return None, None - d = sr.data - l = restolist(d) - return l, sr - -def getprefdir(id): - try: - dr = GetResource('alis', id) - fss, fss_changed = macfs.RawAlias(dr.data).Resolve() - except (MacOS.Error, Res.Error): - return None, None, 1 - return fss, dr, fss_changed - -def getoptions(id): - try: - opr = GetResource('Popt', id) - except (MacOS.Error, Res.Error): - return [0]*9, None - options = map(lambda x: ord(x), opr.data) - while len(options) < 9: - options = options + [0] - return options, opr - -def getgusioptions(id): - try: - opr = GetResource('GU\267I', id) - except (MacOS.Error, Res.Error): - return '????', '????', 0, None - data = opr.data - type = data[GUSIPOS_TYPE:GUSIPOS_TYPE+4] - creator = data[GUSIPOS_CREATOR:GUSIPOS_CREATOR+4] - flags = ord(data[GUSIPOS_FLAGS]) - version = data[GUSIPOS_VERSION:GUSIPOS_VERSION+4] - if version <> GUSIVERSION: - message('GU\267I resource version "%s", fixing to "%s"'%(version, GUSIVERSION)) - flags = 0 - delay = (not not (flags & GUSIFLAGS_DELAY)) - return creator, type, delay, opr - -def setgusioptions(opr, creator, type, delay): - data = opr.data - flags = ord(data[GUSIPOS_FLAGS]) - version = data[GUSIPOS_VERSION:GUSIPOS_VERSION+4] - if version <> GUSIVERSION: - flags = 0x88 - version = GUSIVERSION - if delay: - flags = flags | GUSIFLAGS_DELAY - else: - flags = flags & ~GUSIFLAGS_DELAY - data = type + creator + data[GUSIPOS_SKIP] + chr(flags) + GUSIVERSION + data[GUSIPOS_VERSION+4:] - return data + newpath.append(i) + options['path'] = newpath + return options -def openpreffile(rw): - # Find the preferences folder and our prefs file, create if needed. - vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0) - try: - pnhandle = GetNamedResource('STR ', PREFNAME_NAME) - except Res.Error: - message("No %s resource (old Python?)"%PREFNAME_NAME) - sys.exit(1) - prefname = pnhandle.data[1:] - preff_fss = macfs.FSSpec((vrefnum, dirid, prefname)) - try: - preff_handle = FSpOpenResFile(preff_fss, rw) - except Res.Error: - # Create it - message('No preferences file, creating one...') - FSpCreateResFile(preff_fss, 'Pyth', 'pref', smAllScripts) - preff_handle = FSpOpenResFile(preff_fss, rw) - return preff_handle - -def openapplet(name): - fss = macfs.FSSpec(name) - try: - app_handle = FSpOpenResFile(fss, WRITE) - except Res.Error: - message('File does not have a resource fork.') - sys.exit(0) - return app_handle - def edit_preferences(): - preff_handle = openpreffile(WRITE) - - l, sr = getprefpath(PATH_STRINGS_ID) - if l == None: - message('Cannot find any sys.path resource! (Old python?)') - sys.exit(0) - - fss, dr, fss_changed = getprefdir(DIRECTORY_ID) - if fss == None: - fss = macfs.FSSpec(os.getcwd()) - fss_changed = 1 - - options, opr = getoptions(OPTIONS_ID) - saved_options = options[:] - - creator, type, delaycons, gusi_opr = getgusioptions(GUSI_ID) - saved_gusi_options = creator, type, delaycons - - # Let the user play away - result = interact(l, fss, (options, creator, type, delaycons), - 'System-wide preferences') - - # See what we have to update, and how - if result == None: - sys.exit(0) - - pathlist, nfss, (options, creator, type, delaycons) = result - if nfss != fss: - fss_changed = 1 - - if fss_changed: - alias = nfss.NewAlias() - if dr: - dr.data = alias.data - dr.ChangedResource() - else: - dr = Resource(alias.data) - dr.AddResource('alis', DIRECTORY_ID, '') - - if pathlist != l: - if pathlist == []: - if sr.HomeResFile() == preff_handle: - sr.RemoveResource() - elif sr.HomeResFile() == preff_handle: - sr.data = listtores(pathlist) - sr.ChangedResource() - else: - sr = Resource(listtores(pathlist)) - sr.AddResource('STR#', PATH_STRINGS_ID, '') - - if options != saved_options: - newdata = reduce(lambda x, y: x+chr(y), options, '') - if opr and opr.HomeResFile() == preff_handle: - opr.data = newdata - opr.ChangedResource() - else: - opr = Resource(newdata) - opr.AddResource('Popt', OPTIONS_ID, '') - - if (creator, type, delaycons) != saved_gusi_options: - newdata = setgusioptions(gusi_opr, creator, type, delaycons) - if gusi_opr.HomeResFile() == preff_handle: - gusi_opr.data = newdata - gusi_opr.ChangedResource() - else: - ngusi_opr = Resource(newdata) - ngusi_opr.AddResource('GU\267I', GUSI_ID, '') - - CloseResFile(preff_handle) + handler = pythonprefs.PythonOptions() + result = interact(handler.load(), 'System-wide preferences') + if result: + handler.save(result) def edit_applet(name): - pref_handle = openpreffile(READ) - app_handle = openapplet(name) - - notfound = '' - l, sr = getprefpath(OVERRIDE_PATH_STRINGS_ID) - if l == None: - notfound = 'path' - - l, dummy = getprefpath(PATH_STRINGS_ID) - if l == None: - message('Cannot find any sys.path resource! (Old python?)') - sys.exit(0) - - fss, dr, fss_changed = getprefdir(OVERRIDE_DIRECTORY_ID) - if fss == None: - if notfound: - notfound = notfound + ', directory' - else: - notfound = 'directory' - fss, dummy, dummy2 = getprefdir(DIRECTORY_ID) - if fss == None: - fss = macfs.FSSpec(os.getcwd()) - fss_changed = 1 - - options, opr = getoptions(OVERRIDE_OPTIONS_ID) - if not opr: - if notfound: - notfound = notfound + ', options' - else: - notfound = 'options' - options, dummy = getoptions(OPTIONS_ID) - saved_options = options[:] - - creator, type, delaycons, gusi_opr = getgusioptions(OVERRIDE_GUSI_ID) - if not gusi_opr: - if notfound: - notfound = notfound + ', GUSI options' - else: - notfound = 'GUSI options' - creator, type, delaycons, gusi_opr = getgusioptions(GUSI_ID) - saved_gusi_options = creator, type, delaycons - - dummy = dummy2 = None # Discard them. - - if notfound: - message('Warning: initial %s taken from system-wide defaults'%notfound) - # Let the user play away - result = interact(l, fss, (options, creator, type, delaycons), name) - - # See what we have to update, and how - if result == None: - sys.exit(0) - - pathlist, nfss, (options, creator, type, delaycons) = result - if nfss != fss: - fss_changed = 1 - - if fss_changed: - alias = nfss.NewAlias() - if dr: - dr.data = alias.data - dr.ChangedResource() - else: - dr = Resource(alias.data) - dr.AddResource('alis', OVERRIDE_DIRECTORY_ID, '') - - if pathlist != l: - if pathlist == []: - if sr.HomeResFile() == app_handle: - sr.RemoveResource() - elif sr and sr.HomeResFile() == app_handle: - sr.data = listtores(pathlist) - sr.ChangedResource() - else: - sr = Resource(listtores(pathlist)) - sr.AddResource('STR#', OVERRIDE_PATH_STRINGS_ID, '') - - if options != saved_options: - newdata = reduce(lambda x, y: x+chr(y), options, '') - if opr and opr.HomeResFile() == app_handle: - opr.data = newdata - opr.ChangedResource() - else: - opr = Resource(newdata) - opr.AddResource('Popt', OVERRIDE_OPTIONS_ID, '') - - if (creator, type, delaycons) != saved_gusi_options: - newdata = setgusioptions(gusi_opr, creator, type, delaycons) - id, type, name = gusi_opr.GetResInfo() - if gusi_opr.HomeResFile() == app_handle and id == OVERRIDE_GUSI_ID: - gusi_opr.data = newdata - gusi_opr.ChangedResource() - else: - ngusi_opr = Resource(newdata) - ngusi_opr.AddResource('GU\267I', OVERRIDE_GUSI_ID, '') - - CloseResFile(app_handle) + handler = pythonprefs.AppletOptions(name) + result = interact(handler.load(), os.path.split(name)[1]) + if result: + handler.save(result) def main(): try: |