blob: 3f1e9c8dda7d7b3be393663eff309926de426580 [file] [log] [blame]
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001"""A (less & less) simple Python editor"""
2
3import W
4import Wtraceback
5from Wkeys import *
6
7import macfs
8import MacOS
9import Win
10import Res
11import Evt
12import os
13import imp
14import sys
15import string
16import marshal
17import regex
18
Just van Rossum73efed22000-04-09 19:45:22 +000019try:
Just van Rossum0f2fd162000-10-20 06:36:30 +000020 import Wthreading
Just van Rossum73efed22000-04-09 19:45:22 +000021except ImportError:
Just van Rossum0f2fd162000-10-20 06:36:30 +000022 haveThreading = 0
23else:
24 haveThreading = Wthreading.haveThreading
Just van Rossum73efed22000-04-09 19:45:22 +000025
Just van Rossum40f9b7b1999-01-30 22:39:17 +000026_scriptuntitledcounter = 1
27_wordchars = string.letters + string.digits + "_"
28
29
Just van Rossum73efed22000-04-09 19:45:22 +000030runButtonLabels = ["Run all", "Stop!"]
31runSelButtonLabels = ["Run selection", "Pause!", "Resume"]
32
33
Just van Rossum40f9b7b1999-01-30 22:39:17 +000034class Editor(W.Window):
35
36 def __init__(self, path = "", title = ""):
37 defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
38 global _scriptuntitledcounter
39 if not path:
40 if title:
41 self.title = title
42 else:
43 self.title = "Untitled Script " + `_scriptuntitledcounter`
44 _scriptuntitledcounter = _scriptuntitledcounter + 1
45 text = ""
46 self._creator = W._signature
47 elif os.path.exists(path):
48 path = resolvealiases(path)
49 dir, name = os.path.split(path)
50 self.title = name
51 f = open(path, "rb")
52 text = f.read()
53 f.close()
54 fss = macfs.FSSpec(path)
55 self._creator, filetype = fss.GetCreatorType()
56 else:
57 raise IOError, "file '%s' does not exist" % path
58 self.path = path
59
Just van Rossumc7ba0801999-05-21 21:42:27 +000060 if '\n' in text:
61 import EasyDialogs
62 if string.find(text, '\r\n') >= 0:
63 sourceOS = 'DOS'
64 searchString = '\r\n'
65 else:
66 sourceOS = 'UNIX'
67 searchString = '\n'
Just van Rossum73efed22000-04-09 19:45:22 +000068 change = EasyDialogs.AskYesNoCancel('³%s² contains %s-style line feeds. '
69 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
Just van Rossumc7ba0801999-05-21 21:42:27 +000070 # bug: Cancel is treated as No
71 if change > 0:
72 text = string.replace(text, searchString, '\r')
73 else:
74 change = 0
75
Just van Rossum40f9b7b1999-01-30 22:39:17 +000076 self.settings = {}
77 if self.path:
78 self.readwindowsettings()
79 if self.settings.has_key("windowbounds"):
80 bounds = self.settings["windowbounds"]
81 else:
82 bounds = defaultwindowsize
83 if self.settings.has_key("fontsettings"):
84 self.fontsettings = self.settings["fontsettings"]
85 else:
86 self.fontsettings = defaultfontsettings
87 if self.settings.has_key("tabsize"):
88 try:
89 self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
90 except:
91 self.tabsettings = defaulttabsettings
92 else:
93 self.tabsettings = defaulttabsettings
Just van Rossum40f9b7b1999-01-30 22:39:17 +000094
Just van Rossumc7ba0801999-05-21 21:42:27 +000095 W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000096 self.setupwidgets(text)
Just van Rossumc7ba0801999-05-21 21:42:27 +000097 if change > 0:
Just van Rossum5f740071999-10-30 11:44:25 +000098 self.editgroup.editor.changed = 1
Just van Rossumc7ba0801999-05-21 21:42:27 +000099
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000100 if self.settings.has_key("selection"):
101 selstart, selend = self.settings["selection"]
102 self.setselection(selstart, selend)
103 self.open()
104 self.setinfotext()
105 self.globals = {}
106 self._buf = "" # for write method
107 self.debugging = 0
108 self.profiling = 0
109 if self.settings.has_key("run_as_main"):
110 self.run_as_main = self.settings["run_as_main"]
111 else:
112 self.run_as_main = 0
Just van Rossum0f2fd162000-10-20 06:36:30 +0000113 if self.settings.has_key("run_with_interpreter"):
114 self.run_with_interpreter = self.settings["run_with_interpreter"]
115 else:
116 self.run_with_interpreter = 0
Just van Rossum73efed22000-04-09 19:45:22 +0000117 self._threadstate = (0, 0)
118 self._thread = None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000119
120 def readwindowsettings(self):
121 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000122 resref = Res.FSpOpenResFile(self.path, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000123 except Res.Error:
124 return
125 try:
126 Res.UseResFile(resref)
127 data = Res.Get1Resource('PyWS', 128)
128 self.settings = marshal.loads(data.data)
129 except:
130 pass
131 Res.CloseResFile(resref)
132
133 def writewindowsettings(self):
134 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000135 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000136 except Res.Error:
137 Res.CreateResFile(self.path)
Jack Jansend13c3852000-06-20 21:59:25 +0000138 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000139 try:
140 data = Res.Resource(marshal.dumps(self.settings))
141 Res.UseResFile(resref)
142 try:
143 temp = Res.Get1Resource('PyWS', 128)
144 temp.RemoveResource()
145 except Res.Error:
146 pass
147 data.AddResource('PyWS', 128, "window settings")
148 finally:
149 Res.UpdateResFile(resref)
150 Res.CloseResFile(resref)
151
152 def getsettings(self):
153 self.settings = {}
154 self.settings["windowbounds"] = self.getbounds()
155 self.settings["selection"] = self.getselection()
156 self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
157 self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
158 self.settings["run_as_main"] = self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000159 self.settings["run_with_interpreter"] = self.run_with_interpreter
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000160
161 def get(self):
162 return self.editgroup.editor.get()
163
164 def getselection(self):
165 return self.editgroup.editor.ted.WEGetSelection()
166
167 def setselection(self, selstart, selend):
168 self.editgroup.editor.setselection(selstart, selend)
169
170 def getfilename(self):
171 if self.path:
172 return self.path
173 return '<%s>' % self.title
174
175 def setupwidgets(self, text):
176 topbarheight = 24
177 popfieldwidth = 80
178 self.lastlineno = None
179
180 # make an editor
181 self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
182 editor = W.PyEditor((0, 0, -15,-15), text,
183 fontsettings = self.fontsettings,
184 tabsettings = self.tabsettings,
185 file = self.getfilename())
186
187 # make the widgets
188 self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
189 self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
190 self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
191 self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
192 self.editgroup.editor = editor # add editor *after* scrollbars
193
194 self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
195 self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
196
197 self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
198 self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
199 self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
Just van Rossum73efed22000-04-09 19:45:22 +0000200 self.runbutton = W.Button((5, 4, 80, 16), runButtonLabels[0], self.run)
201 self.runselbutton = W.Button((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000202
203 # bind some keys
204 editor.bind("cmdr", self.runbutton.push)
205 editor.bind("enter", self.runselbutton.push)
206 editor.bind("cmdj", self.domenu_gotoline)
207 editor.bind("cmdd", self.domenu_toggledebugger)
208 editor.bind("<idle>", self.updateselection)
209
210 editor.bind("cmde", searchengine.setfindstring)
211 editor.bind("cmdf", searchengine.show)
212 editor.bind("cmdg", searchengine.findnext)
213 editor.bind("cmdshiftr", searchengine.replace)
214 editor.bind("cmdt", searchengine.replacefind)
215
216 self.linefield.bind("return", self.dolinefield)
217 self.linefield.bind("enter", self.dolinefield)
218 self.linefield.bind("tab", self.dolinefield)
219
220 # intercept clicks
221 editor.bind("<click>", self.clickeditor)
222 self.linefield.bind("<click>", self.clicklinefield)
223
224 def makeoptionsmenu(self):
Just van Rossumedab9391999-02-02 22:31:05 +0000225 menuitems = [('Font settingsŠ', self.domenu_fontsettings),
Just van Rossum12710051999-02-27 17:18:30 +0000226 ("Save optionsŠ", self.domenu_options),
227 '-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000228 ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
Just van Rossum0f2fd162000-10-20 06:36:30 +0000229 #('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_toggle_run_with_interpreter),
230 #'-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000231 ('Modularize', self.domenu_modularize),
Just van Rossumedab9391999-02-02 22:31:05 +0000232 ('Browse namespaceŠ', self.domenu_browsenamespace),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000233 '-']
234 if self.profiling:
235 menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
236 else:
237 menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
238 if self.editgroup.editor._debugger:
239 menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
240 ('Clear breakpoints', self.domenu_clearbreakpoints),
Just van Rossumedab9391999-02-02 22:31:05 +0000241 ('Edit breakpointsŠ', self.domenu_editbreakpoints)]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000242 else:
243 menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
244 self.editgroup.optionsmenu.set(menuitems)
245
246 def domenu_toggle_run_as_main(self):
247 self.run_as_main = not self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000248 self.run_with_interpreter = 0
249 self.editgroup.editor.selchanged = 1
250
251 def domenu_toggle_run_with_interpreter(self):
252 self.run_with_interpreter = not self.run_with_interpreter
253 self.run_as_main = 0
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000254 self.editgroup.editor.selchanged = 1
255
256 def showbreakpoints(self, onoff):
257 self.editgroup.editor.showbreakpoints(onoff)
258 self.debugging = onoff
259
260 def domenu_clearbreakpoints(self, *args):
261 self.editgroup.editor.clearbreakpoints()
262
263 def domenu_editbreakpoints(self, *args):
264 self.editgroup.editor.editbreakpoints()
265
266 def domenu_toggledebugger(self, *args):
267 if not self.debugging:
268 W.SetCursor('watch')
269 self.debugging = not self.debugging
270 self.editgroup.editor.togglebreakpoints()
271
272 def domenu_toggleprofiler(self, *args):
273 self.profiling = not self.profiling
274
275 def domenu_browsenamespace(self, *args):
276 import PyBrowser, W
277 W.SetCursor('watch')
278 globals, file, modname = self.getenvironment()
279 if not modname:
280 modname = self.title
281 PyBrowser.Browser(globals, "Object browser: " + modname)
282
283 def domenu_modularize(self, *args):
284 modname = _filename_as_modname(self.title)
285 if not modname:
Just van Rossumedab9391999-02-02 22:31:05 +0000286 raise W.AlertError, 'Can¹t modularize ³%s²' % self.title
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000287 run_as_main = self.run_as_main
288 self.run_as_main = 0
289 self.run()
290 self.run_as_main = run_as_main
291 if self.path:
292 file = self.path
293 else:
294 file = self.title
295
296 if self.globals and not sys.modules.has_key(modname):
297 module = imp.new_module(modname)
298 for attr in self.globals.keys():
299 setattr(module,attr,self.globals[attr])
300 sys.modules[modname] = module
301 self.globals = {}
302
303 def domenu_fontsettings(self, *args):
304 import FontSettings
305 fontsettings = self.editgroup.editor.getfontsettings()
306 tabsettings = self.editgroup.editor.gettabsettings()
307 settings = FontSettings.FontDialog(fontsettings, tabsettings)
308 if settings:
309 fontsettings, tabsettings = settings
310 self.editgroup.editor.setfontsettings(fontsettings)
311 self.editgroup.editor.settabsettings(tabsettings)
312
Just van Rossum12710051999-02-27 17:18:30 +0000313 def domenu_options(self, *args):
314 rv = SaveOptions(self._creator)
315 if rv:
Just van Rossum3af507d1999-04-22 22:23:46 +0000316 self.editgroup.editor.selchanged = 1 # ouch...
Just van Rossum12710051999-02-27 17:18:30 +0000317 self._creator = rv
318
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000319 def clicklinefield(self):
320 if self._currentwidget <> self.linefield:
321 self.linefield.select(1)
322 self.linefield.selectall()
323 return 1
324
325 def clickeditor(self):
326 if self._currentwidget <> self.editgroup.editor:
327 self.dolinefield()
328 return 1
329
330 def updateselection(self, force = 0):
331 sel = min(self.editgroup.editor.getselection())
332 lineno = self.editgroup.editor.offsettoline(sel)
333 if lineno <> self.lastlineno or force:
334 self.lastlineno = lineno
335 self.linefield.set(str(lineno + 1))
336 self.linefield.selview()
337
338 def dolinefield(self):
339 try:
340 lineno = string.atoi(self.linefield.get()) - 1
341 if lineno <> self.lastlineno:
342 self.editgroup.editor.selectline(lineno)
343 self.updateselection(1)
344 except:
345 self.updateselection(1)
346 self.editgroup.editor.select(1)
347
348 def setinfotext(self):
349 if not hasattr(self, 'infotext'):
350 return
351 if self.path:
352 self.infotext.set(self.path)
353 else:
354 self.infotext.set("")
355
356 def close(self):
357 if self.editgroup.editor.changed:
358 import EasyDialogs
359 import Qd
360 Qd.InitCursor() # XXX should be done by dialog
Just van Rossumedab9391999-02-02 22:31:05 +0000361 save = EasyDialogs.AskYesNoCancel('Save window ³%s² before closing?' % self.title, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000362 if save > 0:
363 if self.domenu_save():
364 return 1
365 elif save < 0:
366 return 1
Just van Rossumc7ba0801999-05-21 21:42:27 +0000367 self.globals = None # XXX doesn't help... all globals leak :-(
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000368 W.Window.close(self)
369
370 def domenu_close(self, *args):
371 return self.close()
372
373 def domenu_save(self, *args):
374 if not self.path:
375 # Will call us recursively
376 return self.domenu_save_as()
377 data = self.editgroup.editor.get()
378 fp = open(self.path, 'wb') # open file in binary mode, data has '\r' line-endings
379 fp.write(data)
380 fp.close()
381 fss = macfs.FSSpec(self.path)
382 fss.SetCreatorType(self._creator, 'TEXT')
383 self.getsettings()
384 self.writewindowsettings()
385 self.editgroup.editor.changed = 0
386 self.editgroup.editor.selchanged = 0
387 import linecache
388 if linecache.cache.has_key(self.path):
389 del linecache.cache[self.path]
390 import macostools
391 macostools.touched(self.path)
392
393 def can_save(self, menuitem):
394 return self.editgroup.editor.changed or self.editgroup.editor.selchanged
395
396 def domenu_save_as(self, *args):
397 fss, ok = macfs.StandardPutFile('Save as:', self.title)
398 if not ok:
399 return 1
400 self.showbreakpoints(0)
401 self.path = fss.as_pathname()
402 self.setinfotext()
403 self.title = os.path.split(self.path)[-1]
404 self.wid.SetWTitle(self.title)
405 self.domenu_save()
406 self.editgroup.editor.setfile(self.getfilename())
407 app = W.getapplication()
408 app.makeopenwindowsmenu()
409 if hasattr(app, 'makescriptsmenu'):
410 app = W.getapplication()
411 fss, fss_changed = app.scriptsfolder.Resolve()
412 path = fss.as_pathname()
413 if path == self.path[:len(path)]:
414 W.getapplication().makescriptsmenu()
415
416 def domenu_save_as_applet(self, *args):
417 try:
418 import buildtools
419 except ImportError:
420 # only have buildtools in Python >= 1.5.2
Just van Rossumedab9391999-02-02 22:31:05 +0000421 raise W.AlertError, "³Save as Applet² is only supported in\rPython 1.5.2 and up."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000422
423 buildtools.DEBUG = 0 # ouch.
424
425 if self.title[-3:] == ".py":
426 destname = self.title[:-3]
427 else:
428 destname = self.title + ".applet"
429 fss, ok = macfs.StandardPutFile('Save as Applet:', destname)
430 if not ok:
431 return 1
432 W.SetCursor("watch")
433 destname = fss.as_pathname()
434 if self.path:
435 filename = self.path
436 if filename[-3:] == ".py":
437 rsrcname = filename[:-3] + '.rsrc'
438 else:
439 rsrcname = filename + '.rsrc'
440 else:
441 filename = self.title
442 rsrcname = ""
443
444 pytext = self.editgroup.editor.get()
445 pytext = string.split(pytext, '\r')
446 pytext = string.join(pytext, '\n') + '\n'
447 try:
448 code = compile(pytext, filename, "exec")
449 except (SyntaxError, EOFError):
450 raise buildtools.BuildError, "Syntax error in script %s" % `filename`
451
452 # Try removing the output file
453 try:
454 os.remove(destname)
455 except os.error:
456 pass
457 template = buildtools.findtemplate()
458 buildtools.process_common(template, None, code, rsrcname, destname, 0, 1)
459
460 def domenu_gotoline(self, *args):
461 self.linefield.selectall()
462 self.linefield.select(1)
463 self.linefield.selectall()
464
465 def domenu_selectline(self, *args):
466 self.editgroup.editor.expandselection()
467
468 def domenu_find(self, *args):
469 searchengine.show()
470
471 def domenu_entersearchstring(self, *args):
472 searchengine.setfindstring()
473
474 def domenu_replace(self, *args):
475 searchengine.replace()
476
477 def domenu_findnext(self, *args):
478 searchengine.findnext()
479
480 def domenu_replacefind(self, *args):
481 searchengine.replacefind()
482
483 def domenu_run(self, *args):
484 self.runbutton.push()
485
486 def domenu_runselection(self, *args):
487 self.runselbutton.push()
488
489 def run(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000490 if self._threadstate == (0, 0):
491 self._run()
492 else:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000493 lock = Wthreading.Lock()
494 lock.acquire()
495 self._thread.postException(KeyboardInterrupt)
496 if self._thread.isBlocked():
Just van Rossum73efed22000-04-09 19:45:22 +0000497 self._thread.start()
Just van Rossum0f2fd162000-10-20 06:36:30 +0000498 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000499
500 def _run(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000501 if self.run_with_interpreter:
502 if self.editgroup.editor.changed:
503 import EasyDialogs
504 import Qd; Qd.InitCursor()
505 save = EasyDialogs.AskYesNoCancel('Save ³%s² before running?' % self.title, 1)
506 if save > 0:
507 if self.domenu_save():
508 return
509 elif save < 0:
510 return
511 if not self.path:
512 raise W.AlertError, "Can't run unsaved file"
513 self._run_with_interpreter()
514 else:
515 pytext = self.editgroup.editor.get()
516 globals, file, modname = self.getenvironment()
517 self.execstring(pytext, globals, globals, file, modname)
518
519 def _run_with_interpreter(self):
520 interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
521 if not os.path.exists(interp_path):
522 raise W.AlertError, "Can't find interpreter"
523 import findertools
524 XXX
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000525
526 def runselection(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000527 if self._threadstate == (0, 0):
528 self._runselection()
529 elif self._threadstate == (1, 1):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000530 self._thread.block()
Just van Rossum73efed22000-04-09 19:45:22 +0000531 self.setthreadstate((1, 2))
532 elif self._threadstate == (1, 2):
533 self._thread.start()
534 self.setthreadstate((1, 1))
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000535
536 def _runselection(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000537 if self.run_with_interpreter:
538 raise W.AlertError, "Can't run selection with Interpreter"
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000539 globals, file, modname = self.getenvironment()
540 locals = globals
541 # select whole lines
542 self.editgroup.editor.expandselection()
543
544 # get lineno of first selected line
545 selstart, selend = self.editgroup.editor.getselection()
546 selstart, selend = min(selstart, selend), max(selstart, selend)
547 selfirstline = self.editgroup.editor.offsettoline(selstart)
548 alltext = self.editgroup.editor.get()
549 pytext = alltext[selstart:selend]
550 lines = string.split(pytext, '\r')
551 indent = getminindent(lines)
552 if indent == 1:
553 classname = ''
554 alllines = string.split(alltext, '\r')
555 identifieRE_match = _identifieRE.match
556 for i in range(selfirstline - 1, -1, -1):
557 line = alllines[i]
558 if line[:6] == 'class ':
559 classname = string.split(string.strip(line[6:]))[0]
560 classend = identifieRE_match(classname)
561 if classend < 1:
Just van Rossumedab9391999-02-02 22:31:05 +0000562 raise W.AlertError, 'Can¹t find a class.'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000563 classname = classname[:classend]
564 break
565 elif line and line[0] not in '\t#':
Just van Rossumedab9391999-02-02 22:31:05 +0000566 raise W.AlertError, 'Can¹t find a class.'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000567 else:
Just van Rossumedab9391999-02-02 22:31:05 +0000568 raise W.AlertError, 'Can¹t find a class.'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000569 if globals.has_key(classname):
570 locals = globals[classname].__dict__
571 else:
Just van Rossumedab9391999-02-02 22:31:05 +0000572 raise W.AlertError, 'Can¹t find class ³%s².' % classname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000573 # dedent to top level
574 for i in range(len(lines)):
575 lines[i] = lines[i][1:]
576 pytext = string.join(lines, '\r')
577 elif indent > 0:
Just van Rossumedab9391999-02-02 22:31:05 +0000578 raise W.AlertError, 'Can¹t run indented code.'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000579
580 # add "newlines" to fool compile/exec:
581 # now a traceback will give the right line number
582 pytext = selfirstline * '\r' + pytext
583 self.execstring(pytext, globals, locals, file, modname)
584
Just van Rossum73efed22000-04-09 19:45:22 +0000585 def setthreadstate(self, state):
586 oldstate = self._threadstate
587 if oldstate[0] <> state[0]:
588 self.runbutton.settitle(runButtonLabels[state[0]])
589 if oldstate[1] <> state[1]:
590 self.runselbutton.settitle(runSelButtonLabels[state[1]])
591 self._threadstate = state
592
593 def _exec_threadwrapper(self, *args, **kwargs):
594 apply(execstring, args, kwargs)
595 self.setthreadstate((0, 0))
596 self._thread = None
597
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000598 def execstring(self, pytext, globals, locals, file, modname):
599 tracebackwindow.hide()
600 # update windows
601 W.getapplication().refreshwindows()
602 if self.run_as_main:
603 modname = "__main__"
604 if self.path:
605 dir = os.path.dirname(self.path)
606 savedir = os.getcwd()
607 os.chdir(dir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000608 sys.path.insert(0, dir)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000609 else:
610 cwdindex = None
611 try:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000612 if haveThreading:
613 self._thread = Wthreading.Thread(os.path.basename(file),
Just van Rossum73efed22000-04-09 19:45:22 +0000614 self._exec_threadwrapper, pytext, globals, locals, file, self.debugging,
615 modname, self.profiling)
616 self.setthreadstate((1, 1))
617 self._thread.start()
618 else:
619 execstring(pytext, globals, locals, file, self.debugging,
620 modname, self.profiling)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000621 finally:
622 if self.path:
623 os.chdir(savedir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000624 del sys.path[0]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000625
626 def getenvironment(self):
627 if self.path:
628 file = self.path
629 dir = os.path.dirname(file)
630 # check if we're part of a package
631 modname = ""
632 while os.path.exists(os.path.join(dir, "__init__.py")):
633 dir, dirname = os.path.split(dir)
Just van Rossum2aaeb521999-02-05 21:58:25 +0000634 modname = dirname + '.' + modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000635 subname = _filename_as_modname(self.title)
636 if modname:
637 if subname == "__init__":
Just van Rossum2aaeb521999-02-05 21:58:25 +0000638 # strip trailing period
639 modname = modname[:-1]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000640 else:
Just van Rossum2aaeb521999-02-05 21:58:25 +0000641 modname = modname + subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000642 else:
643 modname = subname
644 if sys.modules.has_key(modname):
645 globals = sys.modules[modname].__dict__
646 self.globals = {}
647 else:
648 globals = self.globals
Just van Rossum73efed22000-04-09 19:45:22 +0000649 modname = subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000650 else:
651 file = '<%s>' % self.title
652 globals = self.globals
653 modname = file
654 return globals, file, modname
655
656 def write(self, stuff):
657 """for use as stdout"""
658 self._buf = self._buf + stuff
659 if '\n' in self._buf:
660 self.flush()
661
662 def flush(self):
663 stuff = string.split(self._buf, '\n')
664 stuff = string.join(stuff, '\r')
665 end = self.editgroup.editor.ted.WEGetTextLength()
666 self.editgroup.editor.ted.WESetSelection(end, end)
667 self.editgroup.editor.ted.WEInsert(stuff, None, None)
668 self.editgroup.editor.updatescrollbars()
669 self._buf = ""
670 # ? optional:
671 #self.wid.SelectWindow()
672
673 def getclasslist(self):
674 from string import find, strip
Just van Rossum24073ea1999-12-23 15:46:57 +0000675 import re
676 methodRE = re.compile(r"\r[ \t]+def ")
677 findMethod = methodRE.search
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000678 editor = self.editgroup.editor
679 text = editor.get()
680 list = []
681 append = list.append
682 functag = "func"
683 classtag = "class"
684 methodtag = "method"
685 pos = -1
686 if text[:4] == 'def ':
687 append((pos + 4, functag))
688 pos = 4
689 while 1:
690 pos = find(text, '\rdef ', pos + 1)
691 if pos < 0:
692 break
693 append((pos + 5, functag))
694 pos = -1
695 if text[:6] == 'class ':
696 append((pos + 6, classtag))
697 pos = 6
698 while 1:
699 pos = find(text, '\rclass ', pos + 1)
700 if pos < 0:
701 break
702 append((pos + 7, classtag))
703 pos = 0
704 while 1:
Just van Rossum24073ea1999-12-23 15:46:57 +0000705 m = findMethod(text, pos + 1)
706 if m is None:
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000707 break
Just van Rossum24073ea1999-12-23 15:46:57 +0000708 pos = m.regs[0][0]
709 #pos = find(text, '\r\tdef ', pos + 1)
710 append((m.regs[0][1], methodtag))
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000711 list.sort()
712 classlist = []
713 methodlistappend = None
714 offsetToLine = editor.ted.WEOffsetToLine
715 getLineRange = editor.ted.WEGetLineRange
716 append = classlist.append
717 identifieRE_match = _identifieRE.match
718 for pos, tag in list:
719 lineno = offsetToLine(pos)
720 lineStart, lineEnd = getLineRange(lineno)
721 line = strip(text[pos:lineEnd])
722 line = line[:identifieRE_match(line)]
723 if tag is functag:
724 append(("def " + line, lineno + 1))
725 methodlistappend = None
726 elif tag is classtag:
727 append(["class " + line])
728 methodlistappend = classlist[-1].append
729 elif methodlistappend and tag is methodtag:
730 methodlistappend(("def " + line, lineno + 1))
731 return classlist
732
733 def popselectline(self, lineno):
734 self.editgroup.editor.selectline(lineno - 1)
735
736 def selectline(self, lineno, charoffset = 0):
737 self.editgroup.editor.selectline(lineno - 1, charoffset)
738
Just van Rossum12710051999-02-27 17:18:30 +0000739class _saveoptions:
740
741 def __init__(self, creator):
742 self.rv = None
743 self.w = w = W.ModalDialog((240, 140), 'Save options')
744 radiobuttons = []
745 w.label = W.TextBox((8, 8, 80, 18), "File creator:")
Just van Rossum3af507d1999-04-22 22:23:46 +0000746 w.ide_radio = W.RadioButton((8, 22, 160, 18), "This application", radiobuttons, self.ide_hit)
747 w.interp_radio = W.RadioButton((8, 42, 160, 18), "Python Interpreter", radiobuttons, self.interp_hit)
Just van Rossum12710051999-02-27 17:18:30 +0000748 w.other_radio = W.RadioButton((8, 62, 50, 18), "Other:", radiobuttons)
749 w.other_creator = W.EditText((62, 62, 40, 20), creator, self.otherselect)
750 w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
751 w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
752 w.setdefaultbutton(w.okbutton)
753 if creator == 'Pyth':
754 w.interp_radio.set(1)
Just van Rossum3af507d1999-04-22 22:23:46 +0000755 elif creator == W._signature:
Just van Rossum12710051999-02-27 17:18:30 +0000756 w.ide_radio.set(1)
757 else:
758 w.other_radio.set(1)
759 w.bind("cmd.", w.cancelbutton.push)
760 w.open()
761
762 def ide_hit(self):
Just van Rossum3af507d1999-04-22 22:23:46 +0000763 self.w.other_creator.set(W._signature)
Just van Rossum12710051999-02-27 17:18:30 +0000764
765 def interp_hit(self):
766 self.w.other_creator.set("Pyth")
767
768 def otherselect(self, *args):
769 sel_from, sel_to = self.w.other_creator.getselection()
770 creator = self.w.other_creator.get()[:4]
771 creator = creator + " " * (4 - len(creator))
772 self.w.other_creator.set(creator)
773 self.w.other_creator.setselection(sel_from, sel_to)
774 self.w.other_radio.set(1)
775
776 def cancelbuttonhit(self):
777 self.w.close()
778
779 def okbuttonhit(self):
780 self.rv = self.w.other_creator.get()[:4]
781 self.w.close()
782
783
784def SaveOptions(creator):
785 s = _saveoptions(creator)
786 return s.rv
787
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000788
789def _escape(where, what) :
790 return string.join(string.split(where, what), '\\' + what)
791
792def _makewholewordpattern(word):
793 # first, escape special regex chars
794 for esc in "\\[].*^+$?":
795 word = _escape(word, esc)
796 import regex
797 notwordcharspat = '[^' + _wordchars + ']'
798 pattern = '\(' + word + '\)'
799 if word[0] in _wordchars:
800 pattern = notwordcharspat + pattern
801 if word[-1] in _wordchars:
802 pattern = pattern + notwordcharspat
803 return regex.compile(pattern)
804
805class SearchEngine:
806
807 def __init__(self):
808 self.visible = 0
809 self.w = None
810 self.parms = { "find": "",
811 "replace": "",
812 "wrap": 1,
813 "casesens": 1,
814 "wholeword": 1
815 }
816 import MacPrefs
817 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
818 if prefs.searchengine:
819 self.parms["casesens"] = prefs.searchengine.casesens
820 self.parms["wrap"] = prefs.searchengine.wrap
821 self.parms["wholeword"] = prefs.searchengine.wholeword
822
823 def show(self):
824 self.visible = 1
825 if self.w:
826 self.w.wid.ShowWindow()
827 self.w.wid.SelectWindow()
828 self.w.find.edit.select(1)
829 self.w.find.edit.selectall()
830 return
831 self.w = W.Dialog((420, 150), "Find")
832
833 self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
834 self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
835
836 self.w.boxes = W.Group((10, 50, 300, 40))
837 self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
838 self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
839 self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
840
841 self.buttons = [ ("Find", "cmdf", self.find),
842 ("Replace", "cmdr", self.replace),
843 ("Replace all", None, self.replaceall),
Just van Rossumedab9391999-02-02 22:31:05 +0000844 ("Don¹t find", "cmdd", self.dont),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000845 ("Cancel", "cmd.", self.cancel)
846 ]
847 for i in range(len(self.buttons)):
848 bounds = -90, 22 + i * 24, 80, 16
849 title, shortcut, callback = self.buttons[i]
850 self.w[title] = W.Button(bounds, title, callback)
851 if shortcut:
852 self.w.bind(shortcut, self.w[title].push)
Just van Rossumedab9391999-02-02 22:31:05 +0000853 self.w.setdefaultbutton(self.w["Don¹t find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000854 self.w.find.edit.bind("<key>", self.key)
855 self.w.bind("<activate>", self.activate)
856 self.w.bind("<close>", self.close)
857 self.w.open()
858 self.setparms()
859 self.w.find.edit.select(1)
860 self.w.find.edit.selectall()
861 self.checkbuttons()
862
863 def close(self):
864 self.hide()
865 return -1
866
867 def key(self, char, modifiers):
868 self.w.find.edit.key(char, modifiers)
869 self.checkbuttons()
870 return 1
871
872 def activate(self, onoff):
873 if onoff:
874 self.checkbuttons()
875
876 def checkbuttons(self):
877 editor = findeditor(self)
878 if editor:
879 if self.w.find.get():
880 for title, cmd, call in self.buttons[:-2]:
881 self.w[title].enable(1)
882 self.w.setdefaultbutton(self.w["Find"])
883 else:
884 for title, cmd, call in self.buttons[:-2]:
885 self.w[title].enable(0)
Just van Rossumedab9391999-02-02 22:31:05 +0000886 self.w.setdefaultbutton(self.w["Don¹t find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000887 else:
888 for title, cmd, call in self.buttons[:-2]:
889 self.w[title].enable(0)
Just van Rossumedab9391999-02-02 22:31:05 +0000890 self.w.setdefaultbutton(self.w["Don¹t find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000891
892 def find(self):
893 self.getparmsfromwindow()
894 if self.findnext():
895 self.hide()
896
897 def replace(self):
898 editor = findeditor(self)
899 if not editor:
900 return
901 if self.visible:
902 self.getparmsfromwindow()
903 text = editor.getselectedtext()
904 find = self.parms["find"]
905 if not self.parms["casesens"]:
906 find = string.lower(find)
907 text = string.lower(text)
908 if text == find:
909 self.hide()
910 editor.insert(self.parms["replace"])
911
912 def replaceall(self):
913 editor = findeditor(self)
914 if not editor:
915 return
916 if self.visible:
917 self.getparmsfromwindow()
918 W.SetCursor("watch")
919 find = self.parms["find"]
920 if not find:
921 return
922 findlen = len(find)
923 replace = self.parms["replace"]
924 replacelen = len(replace)
925 Text = editor.get()
926 if not self.parms["casesens"]:
927 find = string.lower(find)
928 text = string.lower(Text)
929 else:
930 text = Text
931 newtext = ""
932 pos = 0
933 counter = 0
934 while 1:
935 if self.parms["wholeword"]:
936 wholewordRE = _makewholewordpattern(find)
937 wholewordRE.search(text, pos)
938 if wholewordRE.regs:
939 pos = wholewordRE.regs[1][0]
940 else:
941 pos = -1
942 else:
943 pos = string.find(text, find, pos)
944 if pos < 0:
945 break
946 counter = counter + 1
947 text = text[:pos] + replace + text[pos + findlen:]
948 Text = Text[:pos] + replace + Text[pos + findlen:]
949 pos = pos + replacelen
950 W.SetCursor("arrow")
951 if counter:
952 self.hide()
953 import EasyDialogs
954 import Res
955 editor.changed = 1
956 editor.selchanged = 1
957 editor.ted.WEUseText(Res.Resource(Text))
958 editor.ted.WECalText()
959 editor.SetPort()
Jack Jansen73023402001-01-23 14:58:20 +0000960 editor.GetWindow().InvalWindowRect(editor._bounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000961 #editor.ted.WEUpdate(self.w.wid.GetWindowPort().visRgn)
962 EasyDialogs.Message("Replaced %d occurrences" % counter)
963
964 def dont(self):
965 self.getparmsfromwindow()
966 self.hide()
967
968 def replacefind(self):
969 self.replace()
970 self.findnext()
971
972 def setfindstring(self):
973 editor = findeditor(self)
974 if not editor:
975 return
976 find = editor.getselectedtext()
977 if not find:
978 return
979 self.parms["find"] = find
980 if self.w:
981 self.w.find.edit.set(self.parms["find"])
982 self.w.find.edit.selectall()
983
984 def findnext(self):
985 editor = findeditor(self)
986 if not editor:
987 return
988 find = self.parms["find"]
989 if not find:
990 return
991 text = editor.get()
992 if not self.parms["casesens"]:
993 find = string.lower(find)
994 text = string.lower(text)
995 selstart, selend = editor.getselection()
996 selstart, selend = min(selstart, selend), max(selstart, selend)
997 if self.parms["wholeword"]:
998 wholewordRE = _makewholewordpattern(find)
999 wholewordRE.search(text, selend)
1000 if wholewordRE.regs:
1001 pos = wholewordRE.regs[1][0]
1002 else:
1003 pos = -1
1004 else:
1005 pos = string.find(text, find, selend)
1006 if pos >= 0:
1007 editor.setselection(pos, pos + len(find))
1008 return 1
1009 elif self.parms["wrap"]:
1010 if self.parms["wholeword"]:
1011 wholewordRE.search(text, 0)
1012 if wholewordRE.regs:
1013 pos = wholewordRE.regs[1][0]
1014 else:
1015 pos = -1
1016 else:
1017 pos = string.find(text, find)
1018 if selstart > pos >= 0:
1019 editor.setselection(pos, pos + len(find))
1020 return 1
1021
1022 def setparms(self):
1023 for key, value in self.parms.items():
1024 try:
1025 self.w[key].set(value)
1026 except KeyError:
1027 self.w.boxes[key].set(value)
1028
1029 def getparmsfromwindow(self):
1030 if not self.w:
1031 return
1032 for key, value in self.parms.items():
1033 try:
1034 value = self.w[key].get()
1035 except KeyError:
1036 value = self.w.boxes[key].get()
1037 self.parms[key] = value
1038
1039 def cancel(self):
1040 self.hide()
1041 self.setparms()
1042
1043 def hide(self):
1044 if self.w:
1045 self.w.wid.HideWindow()
1046 self.visible = 0
1047
1048 def writeprefs(self):
1049 import MacPrefs
1050 self.getparmsfromwindow()
1051 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1052 prefs.searchengine.casesens = self.parms["casesens"]
1053 prefs.searchengine.wrap = self.parms["wrap"]
1054 prefs.searchengine.wholeword = self.parms["wholeword"]
1055 prefs.save()
1056
1057
1058class TitledEditText(W.Group):
1059
1060 def __init__(self, possize, title, text = ""):
1061 W.Group.__init__(self, possize)
1062 self.title = W.TextBox((0, 0, 0, 16), title)
1063 self.edit = W.EditText((0, 16, 0, 0), text)
1064
1065 def set(self, value):
1066 self.edit.set(value)
1067
1068 def get(self):
1069 return self.edit.get()
1070
1071
1072class ClassFinder(W.PopupWidget):
1073
1074 def click(self, point, modifiers):
1075 W.SetCursor("watch")
1076 self.set(self._parentwindow.getclasslist())
1077 W.PopupWidget.click(self, point, modifiers)
1078
1079
1080def getminindent(lines):
1081 indent = -1
1082 for line in lines:
1083 stripped = string.strip(line)
1084 if not stripped or stripped[0] == '#':
1085 continue
1086 if indent < 0 or line[:indent] <> indent * '\t':
1087 indent = 0
1088 for c in line:
1089 if c <> '\t':
1090 break
1091 indent = indent + 1
1092 return indent
1093
1094
1095def getoptionkey():
1096 return not not ord(Evt.GetKeys()[7]) & 0x04
1097
1098
1099def execstring(pytext, globals, locals, filename="<string>", debugging=0,
1100 modname="__main__", profiling=0):
1101 if debugging:
1102 import PyDebugger, bdb
1103 BdbQuit = bdb.BdbQuit
1104 else:
1105 BdbQuit = 'BdbQuitDummyException'
1106 pytext = string.split(pytext, '\r')
1107 pytext = string.join(pytext, '\n') + '\n'
1108 W.SetCursor("watch")
1109 globals['__name__'] = modname
1110 globals['__file__'] = filename
1111 sys.argv = [filename]
1112 try:
1113 code = compile(pytext, filename, "exec")
1114 except:
1115 # XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError
1116 # special. That's wrong because THIS case is special (could be literal
1117 # overflow!) and SyntaxError could mean we need a traceback (syntax error
1118 # in imported module!!!
1119 tracebackwindow.traceback(1, filename)
1120 return
1121 try:
1122 if debugging:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001123 if haveThreading:
1124 lock = Wthreading.Lock()
1125 lock.acquire()
Just van Rossum73efed22000-04-09 19:45:22 +00001126 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001127 lock.release()
Just van Rossum73efed22000-04-09 19:45:22 +00001128 else:
1129 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001130 elif not haveThreading:
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001131 MacOS.EnableAppswitch(0)
1132 try:
1133 if profiling:
1134 import profile, ProfileBrowser
1135 p = profile.Profile()
1136 p.set_cmd(filename)
1137 try:
1138 p.runctx(code, globals, locals)
1139 finally:
1140 import pstats
1141
1142 stats = pstats.Stats(p)
1143 ProfileBrowser.ProfileBrowser(stats)
1144 else:
1145 exec code in globals, locals
1146 finally:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001147 if not haveThreading:
Just van Rossum73efed22000-04-09 19:45:22 +00001148 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001149 except W.AlertError, detail:
1150 raise W.AlertError, detail
1151 except (KeyboardInterrupt, BdbQuit):
1152 pass
1153 except:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001154 if haveThreading:
1155 import continuation
1156 lock = Wthreading.Lock()
1157 lock.acquire()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001158 if debugging:
1159 sys.settrace(None)
1160 PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
1161 return
1162 else:
1163 tracebackwindow.traceback(1, filename)
Just van Rossum0f2fd162000-10-20 06:36:30 +00001164 if haveThreading:
1165 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001166 if debugging:
1167 sys.settrace(None)
1168 PyDebugger.stop()
1169
1170
1171_identifieRE = regex.compile("[A-Za-z_][A-Za-z_0-9]*")
1172
1173def _filename_as_modname(fname):
1174 if fname[-3:] == '.py':
1175 modname = fname[:-3]
1176 if _identifieRE.match(modname) == len(modname):
1177 return string.join(string.split(modname, '.'), '_')
1178
1179def findeditor(topwindow, fromtop = 0):
1180 wid = Win.FrontWindow()
1181 if not fromtop:
1182 if topwindow.w and wid == topwindow.w.wid:
1183 wid = topwindow.w.wid.GetNextWindow()
1184 if not wid:
1185 return
1186 app = W.getapplication()
1187 if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
1188 window = W.getapplication()._windows[wid]
1189 else:
1190 return
1191 if not isinstance(window, Editor):
1192 return
1193 return window.editgroup.editor
1194
1195
1196class _EditorDefaultSettings:
1197
1198 def __init__(self):
1199 self.template = "%s, %d point"
1200 self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
1201 self.w = W.Dialog((328, 120), "Editor default settings")
Just van Rossumedab9391999-02-02 22:31:05 +00001202 self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set fontŠ", self.dofont)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001203 self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
1204
1205 self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
1206 self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
1207 self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
1208 self.w.xsize = W.EditText((98, 48, 40, 20), `self.windowsize[0]`)
1209 self.w.ysize = W.EditText((148, 48, 40, 20), `self.windowsize[1]`)
1210
1211 self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
1212 self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
1213 self.w.setdefaultbutton(self.w.okbutton)
1214 self.w.bind('cmd.', self.w.cancelbutton.push)
1215 self.w.open()
1216
1217 def picksize(self):
1218 app = W.getapplication()
1219 editor = findeditor(self)
1220 if editor is not None:
1221 width, height = editor._parentwindow._bounds[2:]
1222 self.w.xsize.set(`width`)
1223 self.w.ysize.set(`height`)
1224 else:
1225 raise W.AlertError, "No edit window found"
1226
1227 def dofont(self):
1228 import FontSettings
1229 settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
1230 if settings:
1231 self.fontsettings, self.tabsettings = settings
1232 sys.exc_traceback = None
1233 self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
1234
1235 def close(self):
1236 self.w.close()
1237 del self.w
1238
1239 def cancel(self):
1240 self.close()
1241
1242 def ok(self):
1243 try:
1244 width = string.atoi(self.w.xsize.get())
1245 except:
1246 self.w.xsize.select(1)
1247 self.w.xsize.selectall()
1248 raise W.AlertError, "Bad number for window width"
1249 try:
1250 height = string.atoi(self.w.ysize.get())
1251 except:
1252 self.w.ysize.select(1)
1253 self.w.ysize.selectall()
1254 raise W.AlertError, "Bad number for window height"
1255 self.windowsize = width, height
1256 seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
1257 self.close()
1258
1259def geteditorprefs():
1260 import MacPrefs
1261 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1262 try:
1263 fontsettings = prefs.pyedit.fontsettings
1264 tabsettings = prefs.pyedit.tabsettings
1265 windowsize = prefs.pyedit.windowsize
1266 except:
1267 fontsettings = prefs.pyedit.fontsettings = ("Python-Sans", 0, 9, (0, 0, 0))
1268 tabsettings = prefs.pyedit.tabsettings = (8, 1)
1269 windowsize = prefs.pyedit.windowsize = (500, 250)
1270 sys.exc_traceback = None
1271 return fontsettings, tabsettings, windowsize
1272
1273def seteditorprefs(fontsettings, tabsettings, windowsize):
1274 import MacPrefs
1275 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1276 prefs.pyedit.fontsettings = fontsettings
1277 prefs.pyedit.tabsettings = tabsettings
1278 prefs.pyedit.windowsize = windowsize
1279 prefs.save()
1280
1281_defaultSettingsEditor = None
1282
1283def EditorDefaultSettings():
1284 global _defaultSettingsEditor
1285 if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
1286 _defaultSettingsEditor = _EditorDefaultSettings()
1287 else:
1288 _defaultSettingsEditor.w.select()
1289
1290def resolvealiases(path):
1291 try:
1292 return macfs.ResolveAliasFile(path)[0].as_pathname()
1293 except (macfs.error, ValueError), (error, str):
1294 if error <> -120:
1295 raise
1296 dir, file = os.path.split(path)
1297 return os.path.join(resolvealiases(dir), file)
1298
1299searchengine = SearchEngine()
1300tracebackwindow = Wtraceback.TraceBack()