blob: 10f583faee045f5e11de8bc22c953178bcfe1fa7 [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
Jack Jansen64aa1e22001-01-29 15:19:17 +00008import MACFS
Just van Rossum40f9b7b1999-01-30 22:39:17 +00009import MacOS
10import Win
11import Res
12import Evt
13import os
14import imp
15import sys
16import string
17import marshal
Jack Jansen9ad27522001-02-21 13:54:31 +000018import re
Just van Rossum40f9b7b1999-01-30 22:39:17 +000019
Just van Rossum73efed22000-04-09 19:45:22 +000020try:
Just van Rossum0f2fd162000-10-20 06:36:30 +000021 import Wthreading
Just van Rossum73efed22000-04-09 19:45:22 +000022except ImportError:
Just van Rossum0f2fd162000-10-20 06:36:30 +000023 haveThreading = 0
24else:
25 haveThreading = Wthreading.haveThreading
Just van Rossum73efed22000-04-09 19:45:22 +000026
Just van Rossum40f9b7b1999-01-30 22:39:17 +000027_scriptuntitledcounter = 1
Jack Jansen9ad27522001-02-21 13:54:31 +000028# _wordchars = string.letters + string.digits + "_"
29_wordchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
Just van Rossum40f9b7b1999-01-30 22:39:17 +000030
31
Just van Rossum73efed22000-04-09 19:45:22 +000032runButtonLabels = ["Run all", "Stop!"]
33runSelButtonLabels = ["Run selection", "Pause!", "Resume"]
34
35
Just van Rossum40f9b7b1999-01-30 22:39:17 +000036class Editor(W.Window):
37
38 def __init__(self, path = "", title = ""):
39 defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
40 global _scriptuntitledcounter
41 if not path:
42 if title:
43 self.title = title
44 else:
45 self.title = "Untitled Script " + `_scriptuntitledcounter`
46 _scriptuntitledcounter = _scriptuntitledcounter + 1
47 text = ""
48 self._creator = W._signature
49 elif os.path.exists(path):
50 path = resolvealiases(path)
51 dir, name = os.path.split(path)
52 self.title = name
53 f = open(path, "rb")
54 text = f.read()
55 f.close()
56 fss = macfs.FSSpec(path)
57 self._creator, filetype = fss.GetCreatorType()
58 else:
59 raise IOError, "file '%s' does not exist" % path
60 self.path = path
61
Just van Rossumc7ba0801999-05-21 21:42:27 +000062 if '\n' in text:
63 import EasyDialogs
64 if string.find(text, '\r\n') >= 0:
65 sourceOS = 'DOS'
66 searchString = '\r\n'
67 else:
68 sourceOS = 'UNIX'
69 searchString = '\n'
Just van Rossumdc3c6172001-06-19 21:37:33 +000070 change = EasyDialogs.AskYesNoCancel('"%s" contains %s-style line feeds. '
Just van Rossum73efed22000-04-09 19:45:22 +000071 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
Just van Rossumc7ba0801999-05-21 21:42:27 +000072 # bug: Cancel is treated as No
73 if change > 0:
74 text = string.replace(text, searchString, '\r')
75 else:
76 change = 0
77
Just van Rossum40f9b7b1999-01-30 22:39:17 +000078 self.settings = {}
79 if self.path:
80 self.readwindowsettings()
81 if self.settings.has_key("windowbounds"):
82 bounds = self.settings["windowbounds"]
83 else:
84 bounds = defaultwindowsize
85 if self.settings.has_key("fontsettings"):
86 self.fontsettings = self.settings["fontsettings"]
87 else:
88 self.fontsettings = defaultfontsettings
89 if self.settings.has_key("tabsize"):
90 try:
91 self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
92 except:
93 self.tabsettings = defaulttabsettings
94 else:
95 self.tabsettings = defaulttabsettings
Just van Rossum40f9b7b1999-01-30 22:39:17 +000096
Just van Rossumc7ba0801999-05-21 21:42:27 +000097 W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000098 self.setupwidgets(text)
Just van Rossumc7ba0801999-05-21 21:42:27 +000099 if change > 0:
Just van Rossum5f740071999-10-30 11:44:25 +0000100 self.editgroup.editor.changed = 1
Just van Rossumc7ba0801999-05-21 21:42:27 +0000101
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000102 if self.settings.has_key("selection"):
103 selstart, selend = self.settings["selection"]
104 self.setselection(selstart, selend)
105 self.open()
106 self.setinfotext()
107 self.globals = {}
108 self._buf = "" # for write method
109 self.debugging = 0
110 self.profiling = 0
111 if self.settings.has_key("run_as_main"):
112 self.run_as_main = self.settings["run_as_main"]
113 else:
114 self.run_as_main = 0
Just van Rossum0f2fd162000-10-20 06:36:30 +0000115 if self.settings.has_key("run_with_interpreter"):
116 self.run_with_interpreter = self.settings["run_with_interpreter"]
117 else:
118 self.run_with_interpreter = 0
Just van Rossum73efed22000-04-09 19:45:22 +0000119 self._threadstate = (0, 0)
120 self._thread = None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000121
122 def readwindowsettings(self):
123 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000124 resref = Res.FSpOpenResFile(self.path, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000125 except Res.Error:
126 return
127 try:
128 Res.UseResFile(resref)
129 data = Res.Get1Resource('PyWS', 128)
130 self.settings = marshal.loads(data.data)
131 except:
132 pass
133 Res.CloseResFile(resref)
134
135 def writewindowsettings(self):
136 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000137 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000138 except Res.Error:
Jack Jansen64aa1e22001-01-29 15:19:17 +0000139 Res.FSpCreateResFile(self.path, self._creator, 'TEXT', MACFS.smAllScripts)
Jack Jansend13c3852000-06-20 21:59:25 +0000140 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000141 try:
142 data = Res.Resource(marshal.dumps(self.settings))
143 Res.UseResFile(resref)
144 try:
145 temp = Res.Get1Resource('PyWS', 128)
146 temp.RemoveResource()
147 except Res.Error:
148 pass
149 data.AddResource('PyWS', 128, "window settings")
150 finally:
151 Res.UpdateResFile(resref)
152 Res.CloseResFile(resref)
153
154 def getsettings(self):
155 self.settings = {}
156 self.settings["windowbounds"] = self.getbounds()
157 self.settings["selection"] = self.getselection()
158 self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
159 self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
160 self.settings["run_as_main"] = self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000161 self.settings["run_with_interpreter"] = self.run_with_interpreter
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000162
163 def get(self):
164 return self.editgroup.editor.get()
165
166 def getselection(self):
167 return self.editgroup.editor.ted.WEGetSelection()
168
169 def setselection(self, selstart, selend):
170 self.editgroup.editor.setselection(selstart, selend)
171
172 def getfilename(self):
173 if self.path:
174 return self.path
175 return '<%s>' % self.title
176
177 def setupwidgets(self, text):
178 topbarheight = 24
179 popfieldwidth = 80
180 self.lastlineno = None
181
182 # make an editor
183 self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
184 editor = W.PyEditor((0, 0, -15,-15), text,
185 fontsettings = self.fontsettings,
186 tabsettings = self.tabsettings,
187 file = self.getfilename())
188
189 # make the widgets
190 self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
191 self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
192 self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
193 self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
194 self.editgroup.editor = editor # add editor *after* scrollbars
195
196 self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
197 self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
198
199 self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
200 self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
201 self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
Just van Rossum73efed22000-04-09 19:45:22 +0000202 self.runbutton = W.Button((5, 4, 80, 16), runButtonLabels[0], self.run)
203 self.runselbutton = W.Button((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000204
205 # bind some keys
206 editor.bind("cmdr", self.runbutton.push)
207 editor.bind("enter", self.runselbutton.push)
208 editor.bind("cmdj", self.domenu_gotoline)
209 editor.bind("cmdd", self.domenu_toggledebugger)
210 editor.bind("<idle>", self.updateselection)
211
212 editor.bind("cmde", searchengine.setfindstring)
213 editor.bind("cmdf", searchengine.show)
214 editor.bind("cmdg", searchengine.findnext)
215 editor.bind("cmdshiftr", searchengine.replace)
216 editor.bind("cmdt", searchengine.replacefind)
217
218 self.linefield.bind("return", self.dolinefield)
219 self.linefield.bind("enter", self.dolinefield)
220 self.linefield.bind("tab", self.dolinefield)
221
222 # intercept clicks
223 editor.bind("<click>", self.clickeditor)
224 self.linefield.bind("<click>", self.clicklinefield)
225
226 def makeoptionsmenu(self):
Just van Rossumdc3c6172001-06-19 21:37:33 +0000227 menuitems = [('Font settings\xc9', self.domenu_fontsettings),
228 ("Save options\xc9", self.domenu_options),
Just van Rossum12710051999-02-27 17:18:30 +0000229 '-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000230 ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
Just van Rossum0f2fd162000-10-20 06:36:30 +0000231 #('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_toggle_run_with_interpreter),
232 #'-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000233 ('Modularize', self.domenu_modularize),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000234 ('Browse namespace\xc9', self.domenu_browsenamespace),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000235 '-']
236 if self.profiling:
237 menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
238 else:
239 menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
240 if self.editgroup.editor._debugger:
241 menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
242 ('Clear breakpoints', self.domenu_clearbreakpoints),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000243 ('Edit breakpoints\xc9', self.domenu_editbreakpoints)]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000244 else:
245 menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
246 self.editgroup.optionsmenu.set(menuitems)
247
248 def domenu_toggle_run_as_main(self):
249 self.run_as_main = not self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000250 self.run_with_interpreter = 0
251 self.editgroup.editor.selchanged = 1
252
253 def domenu_toggle_run_with_interpreter(self):
254 self.run_with_interpreter = not self.run_with_interpreter
255 self.run_as_main = 0
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000256 self.editgroup.editor.selchanged = 1
257
258 def showbreakpoints(self, onoff):
259 self.editgroup.editor.showbreakpoints(onoff)
260 self.debugging = onoff
261
262 def domenu_clearbreakpoints(self, *args):
263 self.editgroup.editor.clearbreakpoints()
264
265 def domenu_editbreakpoints(self, *args):
266 self.editgroup.editor.editbreakpoints()
267
268 def domenu_toggledebugger(self, *args):
269 if not self.debugging:
270 W.SetCursor('watch')
271 self.debugging = not self.debugging
272 self.editgroup.editor.togglebreakpoints()
273
274 def domenu_toggleprofiler(self, *args):
275 self.profiling = not self.profiling
276
277 def domenu_browsenamespace(self, *args):
278 import PyBrowser, W
279 W.SetCursor('watch')
280 globals, file, modname = self.getenvironment()
281 if not modname:
282 modname = self.title
283 PyBrowser.Browser(globals, "Object browser: " + modname)
284
285 def domenu_modularize(self, *args):
286 modname = _filename_as_modname(self.title)
287 if not modname:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000288 raise W.AlertError, "Can't modularize \"%s\"" % self.title
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000289 run_as_main = self.run_as_main
290 self.run_as_main = 0
291 self.run()
292 self.run_as_main = run_as_main
293 if self.path:
294 file = self.path
295 else:
296 file = self.title
297
298 if self.globals and not sys.modules.has_key(modname):
299 module = imp.new_module(modname)
300 for attr in self.globals.keys():
301 setattr(module,attr,self.globals[attr])
302 sys.modules[modname] = module
303 self.globals = {}
304
305 def domenu_fontsettings(self, *args):
306 import FontSettings
307 fontsettings = self.editgroup.editor.getfontsettings()
308 tabsettings = self.editgroup.editor.gettabsettings()
309 settings = FontSettings.FontDialog(fontsettings, tabsettings)
310 if settings:
311 fontsettings, tabsettings = settings
312 self.editgroup.editor.setfontsettings(fontsettings)
313 self.editgroup.editor.settabsettings(tabsettings)
314
Just van Rossum12710051999-02-27 17:18:30 +0000315 def domenu_options(self, *args):
316 rv = SaveOptions(self._creator)
317 if rv:
Just van Rossum3af507d1999-04-22 22:23:46 +0000318 self.editgroup.editor.selchanged = 1 # ouch...
Just van Rossum12710051999-02-27 17:18:30 +0000319 self._creator = rv
320
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000321 def clicklinefield(self):
322 if self._currentwidget <> self.linefield:
323 self.linefield.select(1)
324 self.linefield.selectall()
325 return 1
326
327 def clickeditor(self):
328 if self._currentwidget <> self.editgroup.editor:
329 self.dolinefield()
330 return 1
331
332 def updateselection(self, force = 0):
333 sel = min(self.editgroup.editor.getselection())
334 lineno = self.editgroup.editor.offsettoline(sel)
335 if lineno <> self.lastlineno or force:
336 self.lastlineno = lineno
337 self.linefield.set(str(lineno + 1))
338 self.linefield.selview()
339
340 def dolinefield(self):
341 try:
342 lineno = string.atoi(self.linefield.get()) - 1
343 if lineno <> self.lastlineno:
344 self.editgroup.editor.selectline(lineno)
345 self.updateselection(1)
346 except:
347 self.updateselection(1)
348 self.editgroup.editor.select(1)
349
350 def setinfotext(self):
351 if not hasattr(self, 'infotext'):
352 return
353 if self.path:
354 self.infotext.set(self.path)
355 else:
356 self.infotext.set("")
357
358 def close(self):
359 if self.editgroup.editor.changed:
360 import EasyDialogs
361 import Qd
Just van Rossum25ddc632001-07-05 07:06:26 +0000362 Qd.InitCursor()
363 save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title,
364 default=1, no="Don\xd5t save")
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000365 if save > 0:
366 if self.domenu_save():
367 return 1
368 elif save < 0:
369 return 1
Just van Rossum25ddc632001-07-05 07:06:26 +0000370 self.globals = None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000371 W.Window.close(self)
372
373 def domenu_close(self, *args):
374 return self.close()
375
376 def domenu_save(self, *args):
377 if not self.path:
378 # Will call us recursively
379 return self.domenu_save_as()
380 data = self.editgroup.editor.get()
381 fp = open(self.path, 'wb') # open file in binary mode, data has '\r' line-endings
382 fp.write(data)
383 fp.close()
384 fss = macfs.FSSpec(self.path)
385 fss.SetCreatorType(self._creator, 'TEXT')
386 self.getsettings()
387 self.writewindowsettings()
388 self.editgroup.editor.changed = 0
389 self.editgroup.editor.selchanged = 0
390 import linecache
391 if linecache.cache.has_key(self.path):
392 del linecache.cache[self.path]
393 import macostools
394 macostools.touched(self.path)
395
396 def can_save(self, menuitem):
397 return self.editgroup.editor.changed or self.editgroup.editor.selchanged
398
399 def domenu_save_as(self, *args):
400 fss, ok = macfs.StandardPutFile('Save as:', self.title)
401 if not ok:
402 return 1
403 self.showbreakpoints(0)
404 self.path = fss.as_pathname()
405 self.setinfotext()
406 self.title = os.path.split(self.path)[-1]
407 self.wid.SetWTitle(self.title)
408 self.domenu_save()
409 self.editgroup.editor.setfile(self.getfilename())
410 app = W.getapplication()
411 app.makeopenwindowsmenu()
412 if hasattr(app, 'makescriptsmenu'):
413 app = W.getapplication()
414 fss, fss_changed = app.scriptsfolder.Resolve()
415 path = fss.as_pathname()
416 if path == self.path[:len(path)]:
417 W.getapplication().makescriptsmenu()
418
419 def domenu_save_as_applet(self, *args):
Just van Rossumdc3c6172001-06-19 21:37:33 +0000420 import buildtools
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000421
422 buildtools.DEBUG = 0 # ouch.
423
424 if self.title[-3:] == ".py":
425 destname = self.title[:-3]
426 else:
427 destname = self.title + ".applet"
428 fss, ok = macfs.StandardPutFile('Save as Applet:', destname)
429 if not ok:
430 return 1
431 W.SetCursor("watch")
432 destname = fss.as_pathname()
433 if self.path:
434 filename = self.path
435 if filename[-3:] == ".py":
436 rsrcname = filename[:-3] + '.rsrc'
437 else:
438 rsrcname = filename + '.rsrc'
439 else:
440 filename = self.title
441 rsrcname = ""
442
443 pytext = self.editgroup.editor.get()
444 pytext = string.split(pytext, '\r')
445 pytext = string.join(pytext, '\n') + '\n'
446 try:
447 code = compile(pytext, filename, "exec")
448 except (SyntaxError, EOFError):
449 raise buildtools.BuildError, "Syntax error in script %s" % `filename`
450
451 # Try removing the output file
452 try:
453 os.remove(destname)
454 except os.error:
455 pass
456 template = buildtools.findtemplate()
457 buildtools.process_common(template, None, code, rsrcname, destname, 0, 1)
458
459 def domenu_gotoline(self, *args):
460 self.linefield.selectall()
461 self.linefield.select(1)
462 self.linefield.selectall()
463
464 def domenu_selectline(self, *args):
465 self.editgroup.editor.expandselection()
466
467 def domenu_find(self, *args):
468 searchengine.show()
469
470 def domenu_entersearchstring(self, *args):
471 searchengine.setfindstring()
472
473 def domenu_replace(self, *args):
474 searchengine.replace()
475
476 def domenu_findnext(self, *args):
477 searchengine.findnext()
478
479 def domenu_replacefind(self, *args):
480 searchengine.replacefind()
481
482 def domenu_run(self, *args):
483 self.runbutton.push()
484
485 def domenu_runselection(self, *args):
486 self.runselbutton.push()
487
488 def run(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000489 if self._threadstate == (0, 0):
490 self._run()
491 else:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000492 lock = Wthreading.Lock()
493 lock.acquire()
494 self._thread.postException(KeyboardInterrupt)
495 if self._thread.isBlocked():
Just van Rossum73efed22000-04-09 19:45:22 +0000496 self._thread.start()
Just van Rossum0f2fd162000-10-20 06:36:30 +0000497 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000498
499 def _run(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000500 if self.run_with_interpreter:
501 if self.editgroup.editor.changed:
502 import EasyDialogs
503 import Qd; Qd.InitCursor()
Just van Rossumdc3c6172001-06-19 21:37:33 +0000504 save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
Just van Rossum0f2fd162000-10-20 06:36:30 +0000505 if save > 0:
506 if self.domenu_save():
507 return
508 elif save < 0:
509 return
510 if not self.path:
511 raise W.AlertError, "Can't run unsaved file"
512 self._run_with_interpreter()
513 else:
514 pytext = self.editgroup.editor.get()
515 globals, file, modname = self.getenvironment()
516 self.execstring(pytext, globals, globals, file, modname)
517
518 def _run_with_interpreter(self):
519 interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
520 if not os.path.exists(interp_path):
521 raise W.AlertError, "Can't find interpreter"
522 import findertools
523 XXX
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000524
525 def runselection(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000526 if self._threadstate == (0, 0):
527 self._runselection()
528 elif self._threadstate == (1, 1):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000529 self._thread.block()
Just van Rossum73efed22000-04-09 19:45:22 +0000530 self.setthreadstate((1, 2))
531 elif self._threadstate == (1, 2):
532 self._thread.start()
533 self.setthreadstate((1, 1))
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000534
535 def _runselection(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000536 if self.run_with_interpreter:
537 raise W.AlertError, "Can't run selection with Interpreter"
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000538 globals, file, modname = self.getenvironment()
539 locals = globals
540 # select whole lines
541 self.editgroup.editor.expandselection()
542
543 # get lineno of first selected line
544 selstart, selend = self.editgroup.editor.getselection()
545 selstart, selend = min(selstart, selend), max(selstart, selend)
546 selfirstline = self.editgroup.editor.offsettoline(selstart)
547 alltext = self.editgroup.editor.get()
548 pytext = alltext[selstart:selend]
549 lines = string.split(pytext, '\r')
550 indent = getminindent(lines)
551 if indent == 1:
552 classname = ''
553 alllines = string.split(alltext, '\r')
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000554 for i in range(selfirstline - 1, -1, -1):
555 line = alllines[i]
556 if line[:6] == 'class ':
557 classname = string.split(string.strip(line[6:]))[0]
558 classend = identifieRE_match(classname)
559 if classend < 1:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000560 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000561 classname = classname[:classend]
562 break
563 elif line and line[0] not in '\t#':
Just van Rossumdc3c6172001-06-19 21:37:33 +0000564 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000565 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000566 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000567 if globals.has_key(classname):
Just van Rossum25ddc632001-07-05 07:06:26 +0000568 klass = globals[classname]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000569 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000570 raise W.AlertError, "Can't find class \"%s\"." % classname
Just van Rossum25ddc632001-07-05 07:06:26 +0000571 # add class def
572 pytext = ("class %s:\n" % classname) + pytext
573 selfirstline = selfirstline - 1
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000574 elif indent > 0:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000575 raise W.AlertError, "Can't run indented code."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000576
577 # add "newlines" to fool compile/exec:
578 # now a traceback will give the right line number
579 pytext = selfirstline * '\r' + pytext
580 self.execstring(pytext, globals, locals, file, modname)
Just van Rossum25ddc632001-07-05 07:06:26 +0000581 if indent == 1 and globals[classname] is not klass:
582 # update the class in place
583 klass.__dict__.update(globals[classname].__dict__)
584 globals[classname] = klass
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000585
Just van Rossum73efed22000-04-09 19:45:22 +0000586 def setthreadstate(self, state):
587 oldstate = self._threadstate
588 if oldstate[0] <> state[0]:
589 self.runbutton.settitle(runButtonLabels[state[0]])
590 if oldstate[1] <> state[1]:
591 self.runselbutton.settitle(runSelButtonLabels[state[1]])
592 self._threadstate = state
593
594 def _exec_threadwrapper(self, *args, **kwargs):
595 apply(execstring, args, kwargs)
596 self.setthreadstate((0, 0))
597 self._thread = None
598
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000599 def execstring(self, pytext, globals, locals, file, modname):
600 tracebackwindow.hide()
601 # update windows
602 W.getapplication().refreshwindows()
603 if self.run_as_main:
604 modname = "__main__"
605 if self.path:
606 dir = os.path.dirname(self.path)
607 savedir = os.getcwd()
608 os.chdir(dir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000609 sys.path.insert(0, dir)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000610 else:
611 cwdindex = None
612 try:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000613 if haveThreading:
614 self._thread = Wthreading.Thread(os.path.basename(file),
Just van Rossum73efed22000-04-09 19:45:22 +0000615 self._exec_threadwrapper, pytext, globals, locals, file, self.debugging,
616 modname, self.profiling)
617 self.setthreadstate((1, 1))
618 self._thread.start()
619 else:
620 execstring(pytext, globals, locals, file, self.debugging,
621 modname, self.profiling)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000622 finally:
623 if self.path:
624 os.chdir(savedir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000625 del sys.path[0]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000626
627 def getenvironment(self):
628 if self.path:
629 file = self.path
630 dir = os.path.dirname(file)
631 # check if we're part of a package
632 modname = ""
633 while os.path.exists(os.path.join(dir, "__init__.py")):
634 dir, dirname = os.path.split(dir)
Just van Rossum2aaeb521999-02-05 21:58:25 +0000635 modname = dirname + '.' + modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000636 subname = _filename_as_modname(self.title)
637 if modname:
638 if subname == "__init__":
Just van Rossum2aaeb521999-02-05 21:58:25 +0000639 # strip trailing period
640 modname = modname[:-1]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000641 else:
Just van Rossum2aaeb521999-02-05 21:58:25 +0000642 modname = modname + subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000643 else:
644 modname = subname
645 if sys.modules.has_key(modname):
646 globals = sys.modules[modname].__dict__
647 self.globals = {}
648 else:
649 globals = self.globals
Just van Rossum73efed22000-04-09 19:45:22 +0000650 modname = subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000651 else:
652 file = '<%s>' % self.title
653 globals = self.globals
654 modname = file
655 return globals, file, modname
656
657 def write(self, stuff):
658 """for use as stdout"""
659 self._buf = self._buf + stuff
660 if '\n' in self._buf:
661 self.flush()
662
663 def flush(self):
664 stuff = string.split(self._buf, '\n')
665 stuff = string.join(stuff, '\r')
666 end = self.editgroup.editor.ted.WEGetTextLength()
667 self.editgroup.editor.ted.WESetSelection(end, end)
668 self.editgroup.editor.ted.WEInsert(stuff, None, None)
669 self.editgroup.editor.updatescrollbars()
670 self._buf = ""
671 # ? optional:
672 #self.wid.SelectWindow()
673
674 def getclasslist(self):
675 from string import find, strip
Just van Rossum24073ea1999-12-23 15:46:57 +0000676 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
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000717 for pos, tag in list:
718 lineno = offsetToLine(pos)
719 lineStart, lineEnd = getLineRange(lineno)
720 line = strip(text[pos:lineEnd])
721 line = line[:identifieRE_match(line)]
722 if tag is functag:
723 append(("def " + line, lineno + 1))
724 methodlistappend = None
725 elif tag is classtag:
726 append(["class " + line])
727 methodlistappend = classlist[-1].append
728 elif methodlistappend and tag is methodtag:
729 methodlistappend(("def " + line, lineno + 1))
730 return classlist
731
732 def popselectline(self, lineno):
733 self.editgroup.editor.selectline(lineno - 1)
734
735 def selectline(self, lineno, charoffset = 0):
736 self.editgroup.editor.selectline(lineno - 1, charoffset)
737
Just van Rossum12710051999-02-27 17:18:30 +0000738class _saveoptions:
739
740 def __init__(self, creator):
741 self.rv = None
742 self.w = w = W.ModalDialog((240, 140), 'Save options')
743 radiobuttons = []
744 w.label = W.TextBox((8, 8, 80, 18), "File creator:")
Just van Rossum3af507d1999-04-22 22:23:46 +0000745 w.ide_radio = W.RadioButton((8, 22, 160, 18), "This application", radiobuttons, self.ide_hit)
746 w.interp_radio = W.RadioButton((8, 42, 160, 18), "Python Interpreter", radiobuttons, self.interp_hit)
Just van Rossum12710051999-02-27 17:18:30 +0000747 w.other_radio = W.RadioButton((8, 62, 50, 18), "Other:", radiobuttons)
748 w.other_creator = W.EditText((62, 62, 40, 20), creator, self.otherselect)
749 w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
750 w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
751 w.setdefaultbutton(w.okbutton)
752 if creator == 'Pyth':
753 w.interp_radio.set(1)
Just van Rossum3af507d1999-04-22 22:23:46 +0000754 elif creator == W._signature:
Just van Rossum12710051999-02-27 17:18:30 +0000755 w.ide_radio.set(1)
756 else:
757 w.other_radio.set(1)
758 w.bind("cmd.", w.cancelbutton.push)
759 w.open()
760
761 def ide_hit(self):
Just van Rossum3af507d1999-04-22 22:23:46 +0000762 self.w.other_creator.set(W._signature)
Just van Rossum12710051999-02-27 17:18:30 +0000763
764 def interp_hit(self):
765 self.w.other_creator.set("Pyth")
766
767 def otherselect(self, *args):
768 sel_from, sel_to = self.w.other_creator.getselection()
769 creator = self.w.other_creator.get()[:4]
770 creator = creator + " " * (4 - len(creator))
771 self.w.other_creator.set(creator)
772 self.w.other_creator.setselection(sel_from, sel_to)
773 self.w.other_radio.set(1)
774
775 def cancelbuttonhit(self):
776 self.w.close()
777
778 def okbuttonhit(self):
779 self.rv = self.w.other_creator.get()[:4]
780 self.w.close()
781
782
783def SaveOptions(creator):
784 s = _saveoptions(creator)
785 return s.rv
786
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000787
788def _escape(where, what) :
789 return string.join(string.split(where, what), '\\' + what)
790
791def _makewholewordpattern(word):
792 # first, escape special regex chars
Just van Rossum3eec7622001-07-10 19:25:40 +0000793 for esc in "\\[]()|.*^+$?":
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000794 word = _escape(word, esc)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000795 notwordcharspat = '[^' + _wordchars + ']'
Jack Jansen9ad27522001-02-21 13:54:31 +0000796 pattern = '(' + word + ')'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000797 if word[0] in _wordchars:
798 pattern = notwordcharspat + pattern
799 if word[-1] in _wordchars:
800 pattern = pattern + notwordcharspat
Jack Jansen9ad27522001-02-21 13:54:31 +0000801 return re.compile(pattern)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000802
803class SearchEngine:
804
805 def __init__(self):
806 self.visible = 0
807 self.w = None
808 self.parms = { "find": "",
809 "replace": "",
810 "wrap": 1,
811 "casesens": 1,
812 "wholeword": 1
813 }
814 import MacPrefs
815 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
816 if prefs.searchengine:
817 self.parms["casesens"] = prefs.searchengine.casesens
818 self.parms["wrap"] = prefs.searchengine.wrap
819 self.parms["wholeword"] = prefs.searchengine.wholeword
820
821 def show(self):
822 self.visible = 1
823 if self.w:
824 self.w.wid.ShowWindow()
825 self.w.wid.SelectWindow()
826 self.w.find.edit.select(1)
827 self.w.find.edit.selectall()
828 return
829 self.w = W.Dialog((420, 150), "Find")
830
831 self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
832 self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
833
834 self.w.boxes = W.Group((10, 50, 300, 40))
835 self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
836 self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
837 self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
838
839 self.buttons = [ ("Find", "cmdf", self.find),
840 ("Replace", "cmdr", self.replace),
841 ("Replace all", None, self.replaceall),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000842 ("Don't find", "cmdd", self.dont),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000843 ("Cancel", "cmd.", self.cancel)
844 ]
845 for i in range(len(self.buttons)):
846 bounds = -90, 22 + i * 24, 80, 16
847 title, shortcut, callback = self.buttons[i]
848 self.w[title] = W.Button(bounds, title, callback)
849 if shortcut:
850 self.w.bind(shortcut, self.w[title].push)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000851 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000852 self.w.find.edit.bind("<key>", self.key)
853 self.w.bind("<activate>", self.activate)
854 self.w.bind("<close>", self.close)
855 self.w.open()
856 self.setparms()
857 self.w.find.edit.select(1)
858 self.w.find.edit.selectall()
859 self.checkbuttons()
860
861 def close(self):
862 self.hide()
863 return -1
864
865 def key(self, char, modifiers):
866 self.w.find.edit.key(char, modifiers)
867 self.checkbuttons()
868 return 1
869
870 def activate(self, onoff):
871 if onoff:
872 self.checkbuttons()
873
874 def checkbuttons(self):
875 editor = findeditor(self)
876 if editor:
877 if self.w.find.get():
878 for title, cmd, call in self.buttons[:-2]:
879 self.w[title].enable(1)
880 self.w.setdefaultbutton(self.w["Find"])
881 else:
882 for title, cmd, call in self.buttons[:-2]:
883 self.w[title].enable(0)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000884 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000885 else:
886 for title, cmd, call in self.buttons[:-2]:
887 self.w[title].enable(0)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000888 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000889
890 def find(self):
891 self.getparmsfromwindow()
892 if self.findnext():
893 self.hide()
894
895 def replace(self):
896 editor = findeditor(self)
897 if not editor:
898 return
899 if self.visible:
900 self.getparmsfromwindow()
901 text = editor.getselectedtext()
902 find = self.parms["find"]
903 if not self.parms["casesens"]:
904 find = string.lower(find)
905 text = string.lower(text)
906 if text == find:
907 self.hide()
908 editor.insert(self.parms["replace"])
909
910 def replaceall(self):
911 editor = findeditor(self)
912 if not editor:
913 return
914 if self.visible:
915 self.getparmsfromwindow()
916 W.SetCursor("watch")
917 find = self.parms["find"]
918 if not find:
919 return
920 findlen = len(find)
921 replace = self.parms["replace"]
922 replacelen = len(replace)
923 Text = editor.get()
924 if not self.parms["casesens"]:
925 find = string.lower(find)
926 text = string.lower(Text)
927 else:
928 text = Text
929 newtext = ""
930 pos = 0
931 counter = 0
932 while 1:
933 if self.parms["wholeword"]:
934 wholewordRE = _makewholewordpattern(find)
Jack Jansen9ad27522001-02-21 13:54:31 +0000935 match = wholewordRE.search(text, pos)
936 if match:
937 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000938 else:
939 pos = -1
940 else:
941 pos = string.find(text, find, pos)
942 if pos < 0:
943 break
944 counter = counter + 1
945 text = text[:pos] + replace + text[pos + findlen:]
946 Text = Text[:pos] + replace + Text[pos + findlen:]
947 pos = pos + replacelen
948 W.SetCursor("arrow")
949 if counter:
950 self.hide()
951 import EasyDialogs
952 import Res
953 editor.changed = 1
954 editor.selchanged = 1
955 editor.ted.WEUseText(Res.Resource(Text))
956 editor.ted.WECalText()
957 editor.SetPort()
Jack Jansen73023402001-01-23 14:58:20 +0000958 editor.GetWindow().InvalWindowRect(editor._bounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000959 #editor.ted.WEUpdate(self.w.wid.GetWindowPort().visRgn)
960 EasyDialogs.Message("Replaced %d occurrences" % counter)
961
962 def dont(self):
963 self.getparmsfromwindow()
964 self.hide()
965
966 def replacefind(self):
967 self.replace()
968 self.findnext()
969
970 def setfindstring(self):
971 editor = findeditor(self)
972 if not editor:
973 return
974 find = editor.getselectedtext()
975 if not find:
976 return
977 self.parms["find"] = find
978 if self.w:
979 self.w.find.edit.set(self.parms["find"])
980 self.w.find.edit.selectall()
981
982 def findnext(self):
983 editor = findeditor(self)
984 if not editor:
985 return
986 find = self.parms["find"]
987 if not find:
988 return
989 text = editor.get()
990 if not self.parms["casesens"]:
991 find = string.lower(find)
992 text = string.lower(text)
993 selstart, selend = editor.getselection()
994 selstart, selend = min(selstart, selend), max(selstart, selend)
995 if self.parms["wholeword"]:
996 wholewordRE = _makewholewordpattern(find)
Jack Jansen9ad27522001-02-21 13:54:31 +0000997 match = wholewordRE.search(text, selend)
998 if match:
999 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001000 else:
1001 pos = -1
1002 else:
1003 pos = string.find(text, find, selend)
1004 if pos >= 0:
1005 editor.setselection(pos, pos + len(find))
1006 return 1
1007 elif self.parms["wrap"]:
1008 if self.parms["wholeword"]:
Jack Jansen9ad27522001-02-21 13:54:31 +00001009 match = wholewordRE.search(text, 0)
1010 if match:
1011 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001012 else:
1013 pos = -1
1014 else:
1015 pos = string.find(text, find)
1016 if selstart > pos >= 0:
1017 editor.setselection(pos, pos + len(find))
1018 return 1
1019
1020 def setparms(self):
1021 for key, value in self.parms.items():
1022 try:
1023 self.w[key].set(value)
1024 except KeyError:
1025 self.w.boxes[key].set(value)
1026
1027 def getparmsfromwindow(self):
1028 if not self.w:
1029 return
1030 for key, value in self.parms.items():
1031 try:
1032 value = self.w[key].get()
1033 except KeyError:
1034 value = self.w.boxes[key].get()
1035 self.parms[key] = value
1036
1037 def cancel(self):
1038 self.hide()
1039 self.setparms()
1040
1041 def hide(self):
1042 if self.w:
1043 self.w.wid.HideWindow()
1044 self.visible = 0
1045
1046 def writeprefs(self):
1047 import MacPrefs
1048 self.getparmsfromwindow()
1049 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1050 prefs.searchengine.casesens = self.parms["casesens"]
1051 prefs.searchengine.wrap = self.parms["wrap"]
1052 prefs.searchengine.wholeword = self.parms["wholeword"]
1053 prefs.save()
1054
1055
1056class TitledEditText(W.Group):
1057
1058 def __init__(self, possize, title, text = ""):
1059 W.Group.__init__(self, possize)
1060 self.title = W.TextBox((0, 0, 0, 16), title)
1061 self.edit = W.EditText((0, 16, 0, 0), text)
1062
1063 def set(self, value):
1064 self.edit.set(value)
1065
1066 def get(self):
1067 return self.edit.get()
1068
1069
1070class ClassFinder(W.PopupWidget):
1071
1072 def click(self, point, modifiers):
1073 W.SetCursor("watch")
1074 self.set(self._parentwindow.getclasslist())
1075 W.PopupWidget.click(self, point, modifiers)
1076
1077
1078def getminindent(lines):
1079 indent = -1
1080 for line in lines:
1081 stripped = string.strip(line)
1082 if not stripped or stripped[0] == '#':
1083 continue
1084 if indent < 0 or line[:indent] <> indent * '\t':
1085 indent = 0
1086 for c in line:
1087 if c <> '\t':
1088 break
1089 indent = indent + 1
1090 return indent
1091
1092
1093def getoptionkey():
1094 return not not ord(Evt.GetKeys()[7]) & 0x04
1095
1096
1097def execstring(pytext, globals, locals, filename="<string>", debugging=0,
1098 modname="__main__", profiling=0):
1099 if debugging:
1100 import PyDebugger, bdb
1101 BdbQuit = bdb.BdbQuit
1102 else:
1103 BdbQuit = 'BdbQuitDummyException'
1104 pytext = string.split(pytext, '\r')
1105 pytext = string.join(pytext, '\n') + '\n'
1106 W.SetCursor("watch")
1107 globals['__name__'] = modname
1108 globals['__file__'] = filename
1109 sys.argv = [filename]
1110 try:
1111 code = compile(pytext, filename, "exec")
1112 except:
1113 # XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError
1114 # special. That's wrong because THIS case is special (could be literal
1115 # overflow!) and SyntaxError could mean we need a traceback (syntax error
1116 # in imported module!!!
1117 tracebackwindow.traceback(1, filename)
1118 return
1119 try:
1120 if debugging:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001121 if haveThreading:
1122 lock = Wthreading.Lock()
1123 lock.acquire()
Just van Rossum73efed22000-04-09 19:45:22 +00001124 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001125 lock.release()
Just van Rossum73efed22000-04-09 19:45:22 +00001126 else:
1127 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001128 elif not haveThreading:
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001129 MacOS.EnableAppswitch(0)
1130 try:
1131 if profiling:
1132 import profile, ProfileBrowser
1133 p = profile.Profile()
1134 p.set_cmd(filename)
1135 try:
1136 p.runctx(code, globals, locals)
1137 finally:
1138 import pstats
1139
1140 stats = pstats.Stats(p)
1141 ProfileBrowser.ProfileBrowser(stats)
1142 else:
1143 exec code in globals, locals
1144 finally:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001145 if not haveThreading:
Just van Rossum73efed22000-04-09 19:45:22 +00001146 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001147 except W.AlertError, detail:
1148 raise W.AlertError, detail
1149 except (KeyboardInterrupt, BdbQuit):
1150 pass
1151 except:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001152 if haveThreading:
1153 import continuation
1154 lock = Wthreading.Lock()
1155 lock.acquire()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001156 if debugging:
1157 sys.settrace(None)
1158 PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
1159 return
1160 else:
1161 tracebackwindow.traceback(1, filename)
Just van Rossum0f2fd162000-10-20 06:36:30 +00001162 if haveThreading:
1163 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001164 if debugging:
1165 sys.settrace(None)
1166 PyDebugger.stop()
1167
1168
Just van Rossum3eec7622001-07-10 19:25:40 +00001169_identifieRE = re.compile(r"[A-Za-z_][A-Za-z_0-9]*")
Jack Jansen9ad27522001-02-21 13:54:31 +00001170
1171def identifieRE_match(str):
1172 match = _identifieRE.match(str)
1173 if not match:
1174 return -1
1175 return match.end()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001176
1177def _filename_as_modname(fname):
1178 if fname[-3:] == '.py':
1179 modname = fname[:-3]
Jack Jansen9ad27522001-02-21 13:54:31 +00001180 match = _identifieRE.match(modname)
1181 if match and match.start() == 0 and match.end() == len(modname):
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001182 return string.join(string.split(modname, '.'), '_')
1183
1184def findeditor(topwindow, fromtop = 0):
1185 wid = Win.FrontWindow()
1186 if not fromtop:
1187 if topwindow.w and wid == topwindow.w.wid:
1188 wid = topwindow.w.wid.GetNextWindow()
1189 if not wid:
1190 return
1191 app = W.getapplication()
1192 if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
1193 window = W.getapplication()._windows[wid]
1194 else:
1195 return
1196 if not isinstance(window, Editor):
1197 return
1198 return window.editgroup.editor
1199
1200
1201class _EditorDefaultSettings:
1202
1203 def __init__(self):
1204 self.template = "%s, %d point"
1205 self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
1206 self.w = W.Dialog((328, 120), "Editor default settings")
Just van Rossumdc3c6172001-06-19 21:37:33 +00001207 self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001208 self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
1209
1210 self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
1211 self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
1212 self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
1213 self.w.xsize = W.EditText((98, 48, 40, 20), `self.windowsize[0]`)
1214 self.w.ysize = W.EditText((148, 48, 40, 20), `self.windowsize[1]`)
1215
1216 self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
1217 self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
1218 self.w.setdefaultbutton(self.w.okbutton)
1219 self.w.bind('cmd.', self.w.cancelbutton.push)
1220 self.w.open()
1221
1222 def picksize(self):
1223 app = W.getapplication()
1224 editor = findeditor(self)
1225 if editor is not None:
1226 width, height = editor._parentwindow._bounds[2:]
1227 self.w.xsize.set(`width`)
1228 self.w.ysize.set(`height`)
1229 else:
1230 raise W.AlertError, "No edit window found"
1231
1232 def dofont(self):
1233 import FontSettings
1234 settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
1235 if settings:
1236 self.fontsettings, self.tabsettings = settings
1237 sys.exc_traceback = None
1238 self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
1239
1240 def close(self):
1241 self.w.close()
1242 del self.w
1243
1244 def cancel(self):
1245 self.close()
1246
1247 def ok(self):
1248 try:
1249 width = string.atoi(self.w.xsize.get())
1250 except:
1251 self.w.xsize.select(1)
1252 self.w.xsize.selectall()
1253 raise W.AlertError, "Bad number for window width"
1254 try:
1255 height = string.atoi(self.w.ysize.get())
1256 except:
1257 self.w.ysize.select(1)
1258 self.w.ysize.selectall()
1259 raise W.AlertError, "Bad number for window height"
1260 self.windowsize = width, height
1261 seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
1262 self.close()
1263
1264def geteditorprefs():
1265 import MacPrefs
1266 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1267 try:
1268 fontsettings = prefs.pyedit.fontsettings
1269 tabsettings = prefs.pyedit.tabsettings
1270 windowsize = prefs.pyedit.windowsize
1271 except:
1272 fontsettings = prefs.pyedit.fontsettings = ("Python-Sans", 0, 9, (0, 0, 0))
1273 tabsettings = prefs.pyedit.tabsettings = (8, 1)
1274 windowsize = prefs.pyedit.windowsize = (500, 250)
1275 sys.exc_traceback = None
1276 return fontsettings, tabsettings, windowsize
1277
1278def seteditorprefs(fontsettings, tabsettings, windowsize):
1279 import MacPrefs
1280 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1281 prefs.pyedit.fontsettings = fontsettings
1282 prefs.pyedit.tabsettings = tabsettings
1283 prefs.pyedit.windowsize = windowsize
1284 prefs.save()
1285
1286_defaultSettingsEditor = None
1287
1288def EditorDefaultSettings():
1289 global _defaultSettingsEditor
1290 if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
1291 _defaultSettingsEditor = _EditorDefaultSettings()
1292 else:
1293 _defaultSettingsEditor.w.select()
1294
1295def resolvealiases(path):
1296 try:
1297 return macfs.ResolveAliasFile(path)[0].as_pathname()
1298 except (macfs.error, ValueError), (error, str):
1299 if error <> -120:
1300 raise
1301 dir, file = os.path.split(path)
1302 return os.path.join(resolvealiases(dir), file)
1303
1304searchengine = SearchEngine()
1305tracebackwindow = Wtraceback.TraceBack()