blob: 40a406d787d3cf8e5a462d180e53f386b643d11a [file] [log] [blame]
Jack Jansen7571f301995-07-29 13:48:41 +00001"""Edit the Python Preferences file."""
Jack Jansen822a30b1996-04-10 14:52:18 +00002#
3# This program is getting more and more clunky. It should really
4# be rewritten in a modeless way some time soon.
Jack Jansen7571f301995-07-29 13:48:41 +00005
6from Dlg import *
7from Events import *
8from Res import *
9import string
10import struct
11import macfs
12import MacOS
13import os
14import sys
15import Res # For Res.Error
16
17# resource IDs in our own resources (dialogs, etc)
18MESSAGE_ID = 256
19
Jack Jansen9062fa21995-08-14 12:21:12 +000020DIALOG_ID = 512
Jack Jansen7571f301995-07-29 13:48:41 +000021TEXT_ITEM = 1
22OK_ITEM = 2
23CANCEL_ITEM = 3
Jack Jansendb0bace1996-04-04 15:38:44 +000024DIR_ITEM = 4
25TITLE_ITEM = 5
Jack Jansen822a30b1996-04-10 14:52:18 +000026OPTIONS_ITEM = 7
27
28# The options dialog. There is a correspondence between
29# the dialog item numbers and the option.
30OPT_DIALOG_ID = 513
31# 1 thru 7 are the options
32OD_OK_ITEM = 8
33OD_CANCEL_ITEM = 9
Jack Jansen7571f301995-07-29 13:48:41 +000034
35# Resource IDs in the preferences file
36PATH_STRINGS_ID = 128
37DIRECTORY_ID = 128
Jack Jansendb0bace1996-04-04 15:38:44 +000038OPTIONS_ID = 128
Jack Jansen7571f301995-07-29 13:48:41 +000039
Jack Jansendb0bace1996-04-04 15:38:44 +000040# Override IDs (in the applet)
41OVERRIDE_PATH_STRINGS_ID = 129
42OVERRIDE_DIRECTORY_ID = 129
43OVERRIDE_OPTIONS_ID = 129
44
45READ = 1
Jack Jansen7571f301995-07-29 13:48:41 +000046WRITE = 2
47smAllScripts = -3
48kOnSystemDisk = 0x8000
49
50def restolist(data):
51 """Convert STR# resource data to a list of strings"""
52 if not data:
53 return []
54 num, = struct.unpack('h', data[:2])
55 data = data[2:]
56 rv = []
57 for i in range(num):
58 strlen = ord(data[0])
59 if strlen < 0: strlen = strlen + 256
60 str = data[1:strlen+1]
61 data = data[strlen+1:]
62 rv.append(str)
63 return rv
64
65def listtores(list):
66 """Convert a list of strings to STR# resource data"""
67 rv = struct.pack('h', len(list))
68 for str in list:
69 rv = rv + chr(len(str)) + str
70 return rv
71
72def message(str = "Hello, world!", id = MESSAGE_ID):
73 """Show a simple alert with a text message"""
74 d = GetNewDialog(id, -1)
Jack Jansen822a30b1996-04-10 14:52:18 +000075 d.SetDialogDefaultItem(1)
Jack Jansen7571f301995-07-29 13:48:41 +000076 print 'd=', d
77 tp, h, rect = d.GetDialogItem(2)
78 SetDialogItemText(h, str)
79 while 1:
80 n = ModalDialog(None)
81 if n == 1: break
82
Jack Jansen822a30b1996-04-10 14:52:18 +000083def optinteract(options):
84 """Let the user interact with the options dialog"""
85 old_options = options[:]
86 d = GetNewDialog(OPT_DIALOG_ID, -1)
87 d.SetDialogDefaultItem(OD_OK_ITEM)
88 d.SetDialogCancelItem(OD_CANCEL_ITEM)
89 while 1:
90 for i in range(len(options)):
91 tp, h, rect = d.GetDialogItem(i+1)
92 h.as_Control().SetControlValue(options[i])
93 n = ModalDialog(None)
94 if n == OD_OK_ITEM:
95 return options
96 elif n == OD_CANCEL_ITEM:
97 return old_options
98 elif 1 <= n <= len(options):
99 options[n-1] = (not options[n-1])
100
101
102def interact(list, pythondir, options, title):
Jack Jansen7571f301995-07-29 13:48:41 +0000103 """Let the user interact with the dialog"""
104 opythondir = pythondir
105 try:
106 # Try to go to the "correct" dir for GetDirectory
107 os.chdir(pythondir.as_pathname())
108 except os.error:
109 pass
110 d = GetNewDialog(DIALOG_ID, -1)
Jack Jansendb0bace1996-04-04 15:38:44 +0000111 tp, h, rect = d.GetDialogItem(TITLE_ITEM)
112 SetDialogItemText(h, title)
113 tp, h, rect = d.GetDialogItem(TEXT_ITEM)
Jack Jansen7571f301995-07-29 13:48:41 +0000114 SetDialogItemText(h, string.joinfields(list, '\r'))
Jack Jansendb0bace1996-04-04 15:38:44 +0000115## d.SetDialogDefaultItem(OK_ITEM)
116 d.SetDialogCancelItem(CANCEL_ITEM)
Jack Jansen7571f301995-07-29 13:48:41 +0000117 while 1:
118 n = ModalDialog(None)
119 if n == OK_ITEM:
120 break
121 if n == CANCEL_ITEM:
122 return None
Jack Jansendb0bace1996-04-04 15:38:44 +0000123## if n == REVERT_ITEM:
124## return [], pythondir
Jack Jansen7571f301995-07-29 13:48:41 +0000125 if n == DIR_ITEM:
Jack Jansen9062fa21995-08-14 12:21:12 +0000126 fss, ok = macfs.GetDirectory('Select python home folder:')
Jack Jansen7571f301995-07-29 13:48:41 +0000127 if ok:
128 pythondir = fss
Jack Jansen822a30b1996-04-10 14:52:18 +0000129 if n == OPTIONS_ITEM:
130 options = optinteract(options)
Jack Jansen7571f301995-07-29 13:48:41 +0000131 tmp = string.splitfields(GetDialogItemText(h), '\r')
132 rv = []
133 for i in tmp:
134 if i:
135 rv.append(i)
Jack Jansen822a30b1996-04-10 14:52:18 +0000136 return rv, pythondir, options
Jack Jansen7571f301995-07-29 13:48:41 +0000137
Jack Jansendb0bace1996-04-04 15:38:44 +0000138def getprefpath(id):
139 # Load the path and directory resources
Jack Jansen7571f301995-07-29 13:48:41 +0000140 try:
Jack Jansendb0bace1996-04-04 15:38:44 +0000141 sr = GetResource('STR#', id)
142 except (MacOS.Error, Res.Error):
143 return None, None
144 d = sr.data
145 l = restolist(d)
146 return l, sr
147
148def getprefdir(id):
149 try:
150 dr = GetResource('alis', id)
151 fss, fss_changed = macfs.RawAlias(dr.data).Resolve()
152 except (MacOS.Error, Res.Error):
153 return None, None, 1
154 return fss, dr, fss_changed
Jack Jansen822a30b1996-04-10 14:52:18 +0000155
156def getoptions(id):
157 try:
158 opr = GetResource('Popt', id)
159 except (MacOS.Error, Res.Error):
160 return [0]*7, None
161 return map(lambda x: ord(x), opr.data), opr
Jack Jansen7571f301995-07-29 13:48:41 +0000162
Jack Jansendb0bace1996-04-04 15:38:44 +0000163def openpreffile(rw):
Jack Jansen7571f301995-07-29 13:48:41 +0000164 # Find the preferences folder and our prefs file, create if needed.
165 vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0)
166 preff_fss = macfs.FSSpec((vrefnum, dirid, 'Python Preferences'))
167 try:
Jack Jansendb0bace1996-04-04 15:38:44 +0000168 preff_handle = FSpOpenResFile(preff_fss, rw)
Jack Jansen7571f301995-07-29 13:48:41 +0000169 except Res.Error:
170 # Create it
171 message('No preferences file, creating one...')
Jack Jansen532e3c21996-02-21 15:36:26 +0000172 FSpCreateResFile(preff_fss, 'Pyth', 'pref', smAllScripts)
Jack Jansendb0bace1996-04-04 15:38:44 +0000173 preff_handle = FSpOpenResFile(preff_fss, rw)
174 return preff_handle
175
176def openapplet(name):
177 fss = macfs.FSSpec(name)
Jack Jansen7571f301995-07-29 13:48:41 +0000178 try:
Jack Jansendb0bace1996-04-04 15:38:44 +0000179 app_handle = FSpOpenResFile(fss, WRITE)
180 except Res.Error:
181 message('File does not have a resource fork.')
182 sys.exit(0)
183 return app_handle
184
185
186def edit_preferences():
187 preff_handle = openpreffile(WRITE)
188
189 l, sr = getprefpath(PATH_STRINGS_ID)
190 if l == None:
Jack Jansen7571f301995-07-29 13:48:41 +0000191 message('Cannot find any sys.path resource! (Old python?)')
192 sys.exit(0)
Jack Jansendb0bace1996-04-04 15:38:44 +0000193
194 fss, dr, fss_changed = getprefdir(DIRECTORY_ID)
195 if fss == None:
Jack Jansen7571f301995-07-29 13:48:41 +0000196 fss = macfs.FSSpec(os.getcwd())
197 fss_changed = 1
Jack Jansen822a30b1996-04-10 14:52:18 +0000198
199 options, opr = getoptions(OPTIONS_ID)
200 saved_options = options[:]
Jack Jansen7571f301995-07-29 13:48:41 +0000201
202 # Let the user play away
Jack Jansen822a30b1996-04-10 14:52:18 +0000203 result = interact(l, fss, options, 'System-wide preferences')
Jack Jansen7571f301995-07-29 13:48:41 +0000204
205 # See what we have to update, and how
206 if result == None:
207 sys.exit(0)
208
Jack Jansen822a30b1996-04-10 14:52:18 +0000209 pathlist, nfss, options = result
Jack Jansen7571f301995-07-29 13:48:41 +0000210 if nfss != fss:
211 fss_changed = 1
212
Jack Jansen822a30b1996-04-10 14:52:18 +0000213 if fss_changed:
214 alias = nfss.NewAlias()
215 if dr:
216 dr.data = alias.data
217 dr.ChangedResource()
218 else:
219 dr = Resource(alias.data)
220 dr.AddResource('alis', DIRECTORY_ID, '')
221
222 if pathlist != l:
223 if pathlist == []:
224 if sr.HomeResFile() == preff_handle:
225 sr.RemoveResource()
226 elif sr.HomeResFile() == preff_handle:
227 sr.data = listtores(pathlist)
228 sr.ChangedResource()
229 else:
230 sr = Resource(listtores(pathlist))
231 sr.AddResource('STR#', PATH_STRINGS_ID, '')
232
233 if options != saved_options:
234 newdata = reduce(lambda x, y: x+chr(y), options, '')
235 if opr and opr.HomeResFile() == preff_handle:
236 opr.data = newdata
237 opr.ChangedResource()
238 else:
239 opr = Resource(newdata)
240 opr.AddResource('Popt', OPTIONS_ID, '')
Jack Jansen7571f301995-07-29 13:48:41 +0000241
242 CloseResFile(preff_handle)
Jack Jansendb0bace1996-04-04 15:38:44 +0000243
244def edit_applet(name):
245 pref_handle = openpreffile(READ)
246 app_handle = openapplet(name)
247
248 notfound = ''
249 l, sr = getprefpath(OVERRIDE_PATH_STRINGS_ID)
250 if l == None:
251 notfound = 'path'
252
253 l, dummy = getprefpath(PATH_STRINGS_ID)
254 if l == None:
255 message('Cannot find any sys.path resource! (Old python?)')
256 sys.exit(0)
257
258 fss, dr, fss_changed = getprefdir(OVERRIDE_DIRECTORY_ID)
259 if fss == None:
260 if notfound:
Jack Jansen822a30b1996-04-10 14:52:18 +0000261 notfound = notfound + ', directory'
Jack Jansendb0bace1996-04-04 15:38:44 +0000262 else:
263 notfound = 'directory'
264 fss, dummy, dummy2 = getprefdir(DIRECTORY_ID)
265 if fss == None:
266 fss = macfs.FSSpec(os.getcwd())
267 fss_changed = 1
Jack Jansen822a30b1996-04-10 14:52:18 +0000268
269 options, opr = getoptions(OVERRIDE_OPTIONS_ID)
270 if not opr:
271 if notfound:
272 notfound = notfound + ', options'
273 else:
274 notfound = 'options'
275 options, dummy = getoptions(OPTIONS_ID)
276 saved_options = options[:]
Jack Jansendb0bace1996-04-04 15:38:44 +0000277
278 dummy = dummy2 = None # Discard them.
279
280 if notfound:
281 message('Warning: initial %s taken from system-wide defaults'%notfound)
282 # Let the user play away
Jack Jansen822a30b1996-04-10 14:52:18 +0000283 result = interact(l, fss, options, name)
Jack Jansendb0bace1996-04-04 15:38:44 +0000284
285 # See what we have to update, and how
286 if result == None:
287 sys.exit(0)
288
Jack Jansen822a30b1996-04-10 14:52:18 +0000289 pathlist, nfss, options = result
Jack Jansendb0bace1996-04-04 15:38:44 +0000290 if nfss != fss:
291 fss_changed = 1
292
Jack Jansen822a30b1996-04-10 14:52:18 +0000293 if fss_changed:
294 alias = nfss.NewAlias()
295 if dr:
296 dr.data = alias.data
297 dr.ChangedResource()
298 else:
299 dr = Resource(alias.data)
300 dr.AddResource('alis', OVERRIDE_DIRECTORY_ID, '')
301
302 if pathlist != l:
303 if pathlist == []:
304 if sr.HomeResFile() == app_handle:
305 sr.RemoveResource()
306 elif sr and sr.HomeResFile() == app_handle:
307 sr.data = listtores(pathlist)
308 sr.ChangedResource()
309 else:
310 sr = Resource(listtores(pathlist))
311 sr.AddResource('STR#', OVERRIDE_PATH_STRINGS_ID, '')
312
313 if options != saved_options:
314 newdata = reduce(lambda x, y: x+chr(y), options, '')
315 if opr and opr.HomeResFile() == app_handle:
316 opr.data = newdata
317 opr.ChangedResource()
318 else:
319 opr = Resource(newdata)
320 opr.AddResource('Popt', OVERRIDE_OPTIONS_ID, '')
Jack Jansendb0bace1996-04-04 15:38:44 +0000321
322 CloseResFile(app_handle)
323
324def main():
325 try:
326 h = OpenResFile('EditPythonPrefs.rsrc')
327 except Res.Error:
328 pass # Assume we already have acces to our own resource
329
330 if len(sys.argv) <= 1:
331 edit_preferences()
332 else:
333 for appl in sys.argv[1:]:
334 edit_applet(appl)
335
Jack Jansen7571f301995-07-29 13:48:41 +0000336
337if __name__ == '__main__':
338 print # Stupid, to init toolboxes...
339 main()