blob: fcbdc0902e2bf61b4a06e27945bccfed89a021fd [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
Jack Jansen5a6fdcd2001-08-25 12:15:04 +000010from Carbon import Win
11from Carbon import Res
12from Carbon import Evt
Just van Rossum40f9b7b1999-01-30 22:39:17 +000013import 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 Rossum40144012002-02-04 12:52:44 +000020if hasattr(Win, "FrontNonFloatingWindow"):
21 MyFrontWindow = Win.FrontNonFloatingWindow
22else:
23 MyFrontWindow = Win.FrontWindow
24
25
Just van Rossum73efed22000-04-09 19:45:22 +000026try:
Just van Rossum0f2fd162000-10-20 06:36:30 +000027 import Wthreading
Just van Rossum73efed22000-04-09 19:45:22 +000028except ImportError:
Just van Rossum0f2fd162000-10-20 06:36:30 +000029 haveThreading = 0
30else:
31 haveThreading = Wthreading.haveThreading
Just van Rossum73efed22000-04-09 19:45:22 +000032
Just van Rossum40f9b7b1999-01-30 22:39:17 +000033_scriptuntitledcounter = 1
Fred Drake79e75e12001-07-20 19:05:50 +000034_wordchars = string.ascii_letters + string.digits + "_"
Just van Rossum40f9b7b1999-01-30 22:39:17 +000035
36
Just van Rossum73efed22000-04-09 19:45:22 +000037runButtonLabels = ["Run all", "Stop!"]
38runSelButtonLabels = ["Run selection", "Pause!", "Resume"]
39
40
Just van Rossum40f9b7b1999-01-30 22:39:17 +000041class Editor(W.Window):
42
43 def __init__(self, path = "", title = ""):
44 defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
45 global _scriptuntitledcounter
46 if not path:
47 if title:
48 self.title = title
49 else:
50 self.title = "Untitled Script " + `_scriptuntitledcounter`
51 _scriptuntitledcounter = _scriptuntitledcounter + 1
52 text = ""
53 self._creator = W._signature
54 elif os.path.exists(path):
55 path = resolvealiases(path)
56 dir, name = os.path.split(path)
57 self.title = name
58 f = open(path, "rb")
59 text = f.read()
60 f.close()
61 fss = macfs.FSSpec(path)
62 self._creator, filetype = fss.GetCreatorType()
63 else:
64 raise IOError, "file '%s' does not exist" % path
65 self.path = path
66
Just van Rossumc7ba0801999-05-21 21:42:27 +000067 if '\n' in text:
68 import EasyDialogs
69 if string.find(text, '\r\n') >= 0:
70 sourceOS = 'DOS'
71 searchString = '\r\n'
72 else:
73 sourceOS = 'UNIX'
74 searchString = '\n'
Just van Rossumdc3c6172001-06-19 21:37:33 +000075 change = EasyDialogs.AskYesNoCancel('"%s" contains %s-style line feeds. '
Just van Rossum73efed22000-04-09 19:45:22 +000076 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
Just van Rossumc7ba0801999-05-21 21:42:27 +000077 # bug: Cancel is treated as No
78 if change > 0:
79 text = string.replace(text, searchString, '\r')
80 else:
81 change = 0
82
Just van Rossum40f9b7b1999-01-30 22:39:17 +000083 self.settings = {}
84 if self.path:
85 self.readwindowsettings()
86 if self.settings.has_key("windowbounds"):
87 bounds = self.settings["windowbounds"]
88 else:
89 bounds = defaultwindowsize
90 if self.settings.has_key("fontsettings"):
91 self.fontsettings = self.settings["fontsettings"]
92 else:
93 self.fontsettings = defaultfontsettings
94 if self.settings.has_key("tabsize"):
95 try:
96 self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
97 except:
98 self.tabsettings = defaulttabsettings
99 else:
100 self.tabsettings = defaulttabsettings
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000101
Just van Rossumc7ba0801999-05-21 21:42:27 +0000102 W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000103 self.setupwidgets(text)
Just van Rossumc7ba0801999-05-21 21:42:27 +0000104 if change > 0:
Just van Rossumf7f93882001-11-02 19:24:41 +0000105 self.editgroup.editor.textchanged()
Just van Rossumc7ba0801999-05-21 21:42:27 +0000106
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000107 if self.settings.has_key("selection"):
108 selstart, selend = self.settings["selection"]
109 self.setselection(selstart, selend)
110 self.open()
111 self.setinfotext()
112 self.globals = {}
113 self._buf = "" # for write method
114 self.debugging = 0
115 self.profiling = 0
116 if self.settings.has_key("run_as_main"):
117 self.run_as_main = self.settings["run_as_main"]
118 else:
119 self.run_as_main = 0
Just van Rossum0f2fd162000-10-20 06:36:30 +0000120 if self.settings.has_key("run_with_interpreter"):
121 self.run_with_interpreter = self.settings["run_with_interpreter"]
122 else:
123 self.run_with_interpreter = 0
Just van Rossum73efed22000-04-09 19:45:22 +0000124 self._threadstate = (0, 0)
125 self._thread = None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000126
127 def readwindowsettings(self):
128 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000129 resref = Res.FSpOpenResFile(self.path, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000130 except Res.Error:
131 return
132 try:
133 Res.UseResFile(resref)
134 data = Res.Get1Resource('PyWS', 128)
135 self.settings = marshal.loads(data.data)
136 except:
137 pass
138 Res.CloseResFile(resref)
139
140 def writewindowsettings(self):
141 try:
Jack Jansend13c3852000-06-20 21:59:25 +0000142 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000143 except Res.Error:
Jack Jansen64aa1e22001-01-29 15:19:17 +0000144 Res.FSpCreateResFile(self.path, self._creator, 'TEXT', MACFS.smAllScripts)
Jack Jansend13c3852000-06-20 21:59:25 +0000145 resref = Res.FSpOpenResFile(self.path, 3)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000146 try:
147 data = Res.Resource(marshal.dumps(self.settings))
148 Res.UseResFile(resref)
149 try:
150 temp = Res.Get1Resource('PyWS', 128)
151 temp.RemoveResource()
152 except Res.Error:
153 pass
154 data.AddResource('PyWS', 128, "window settings")
155 finally:
156 Res.UpdateResFile(resref)
157 Res.CloseResFile(resref)
158
159 def getsettings(self):
160 self.settings = {}
161 self.settings["windowbounds"] = self.getbounds()
162 self.settings["selection"] = self.getselection()
163 self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
164 self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
165 self.settings["run_as_main"] = self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000166 self.settings["run_with_interpreter"] = self.run_with_interpreter
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000167
168 def get(self):
169 return self.editgroup.editor.get()
170
171 def getselection(self):
172 return self.editgroup.editor.ted.WEGetSelection()
173
174 def setselection(self, selstart, selend):
175 self.editgroup.editor.setselection(selstart, selend)
176
177 def getfilename(self):
178 if self.path:
179 return self.path
180 return '<%s>' % self.title
181
182 def setupwidgets(self, text):
Just van Rossumf376ef02001-11-18 14:12:43 +0000183 topbarheight = 24
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000184 popfieldwidth = 80
185 self.lastlineno = None
186
187 # make an editor
188 self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
189 editor = W.PyEditor((0, 0, -15,-15), text,
190 fontsettings = self.fontsettings,
191 tabsettings = self.tabsettings,
192 file = self.getfilename())
193
194 # make the widgets
195 self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
196 self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
197 self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
198 self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
199 self.editgroup.editor = editor # add editor *after* scrollbars
200
201 self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
202 self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
203
204 self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
205 self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
Just van Rossumf376ef02001-11-18 14:12:43 +0000206 self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
207 self.runbutton = W.BevelButton((6, 4, 80, 16), runButtonLabels[0], self.run)
208 self.runselbutton = W.BevelButton((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000209
210 # bind some keys
211 editor.bind("cmdr", self.runbutton.push)
212 editor.bind("enter", self.runselbutton.push)
213 editor.bind("cmdj", self.domenu_gotoline)
214 editor.bind("cmdd", self.domenu_toggledebugger)
215 editor.bind("<idle>", self.updateselection)
216
217 editor.bind("cmde", searchengine.setfindstring)
218 editor.bind("cmdf", searchengine.show)
219 editor.bind("cmdg", searchengine.findnext)
220 editor.bind("cmdshiftr", searchengine.replace)
221 editor.bind("cmdt", searchengine.replacefind)
222
223 self.linefield.bind("return", self.dolinefield)
224 self.linefield.bind("enter", self.dolinefield)
225 self.linefield.bind("tab", self.dolinefield)
226
227 # intercept clicks
228 editor.bind("<click>", self.clickeditor)
229 self.linefield.bind("<click>", self.clicklinefield)
230
231 def makeoptionsmenu(self):
Just van Rossumdc3c6172001-06-19 21:37:33 +0000232 menuitems = [('Font settings\xc9', self.domenu_fontsettings),
233 ("Save options\xc9", self.domenu_options),
Just van Rossum12710051999-02-27 17:18:30 +0000234 '-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000235 ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
Just van Rossum0f2fd162000-10-20 06:36:30 +0000236 #('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_toggle_run_with_interpreter),
237 #'-',
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000238 ('Modularize', self.domenu_modularize),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000239 ('Browse namespace\xc9', self.domenu_browsenamespace),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000240 '-']
241 if self.profiling:
242 menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
243 else:
244 menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
245 if self.editgroup.editor._debugger:
246 menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
247 ('Clear breakpoints', self.domenu_clearbreakpoints),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000248 ('Edit breakpoints\xc9', self.domenu_editbreakpoints)]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000249 else:
250 menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
251 self.editgroup.optionsmenu.set(menuitems)
252
253 def domenu_toggle_run_as_main(self):
254 self.run_as_main = not self.run_as_main
Just van Rossum0f2fd162000-10-20 06:36:30 +0000255 self.run_with_interpreter = 0
Just van Rossumf7f93882001-11-02 19:24:41 +0000256 self.editgroup.editor.selectionchanged()
Just van Rossum0f2fd162000-10-20 06:36:30 +0000257
258 def domenu_toggle_run_with_interpreter(self):
259 self.run_with_interpreter = not self.run_with_interpreter
260 self.run_as_main = 0
Just van Rossumf7f93882001-11-02 19:24:41 +0000261 self.editgroup.editor.selectionchanged()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000262
263 def showbreakpoints(self, onoff):
264 self.editgroup.editor.showbreakpoints(onoff)
265 self.debugging = onoff
266
267 def domenu_clearbreakpoints(self, *args):
268 self.editgroup.editor.clearbreakpoints()
269
270 def domenu_editbreakpoints(self, *args):
271 self.editgroup.editor.editbreakpoints()
272
273 def domenu_toggledebugger(self, *args):
274 if not self.debugging:
275 W.SetCursor('watch')
276 self.debugging = not self.debugging
277 self.editgroup.editor.togglebreakpoints()
278
279 def domenu_toggleprofiler(self, *args):
280 self.profiling = not self.profiling
281
282 def domenu_browsenamespace(self, *args):
283 import PyBrowser, W
284 W.SetCursor('watch')
285 globals, file, modname = self.getenvironment()
286 if not modname:
287 modname = self.title
288 PyBrowser.Browser(globals, "Object browser: " + modname)
289
290 def domenu_modularize(self, *args):
291 modname = _filename_as_modname(self.title)
292 if not modname:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000293 raise W.AlertError, "Can't modularize \"%s\"" % self.title
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000294 run_as_main = self.run_as_main
295 self.run_as_main = 0
296 self.run()
297 self.run_as_main = run_as_main
298 if self.path:
299 file = self.path
300 else:
301 file = self.title
302
303 if self.globals and not sys.modules.has_key(modname):
304 module = imp.new_module(modname)
305 for attr in self.globals.keys():
306 setattr(module,attr,self.globals[attr])
307 sys.modules[modname] = module
308 self.globals = {}
309
310 def domenu_fontsettings(self, *args):
311 import FontSettings
312 fontsettings = self.editgroup.editor.getfontsettings()
313 tabsettings = self.editgroup.editor.gettabsettings()
314 settings = FontSettings.FontDialog(fontsettings, tabsettings)
315 if settings:
316 fontsettings, tabsettings = settings
317 self.editgroup.editor.setfontsettings(fontsettings)
318 self.editgroup.editor.settabsettings(tabsettings)
319
Just van Rossum12710051999-02-27 17:18:30 +0000320 def domenu_options(self, *args):
321 rv = SaveOptions(self._creator)
322 if rv:
Just van Rossumf7f93882001-11-02 19:24:41 +0000323 self.editgroup.editor.selectionchanged() # ouch...
Just van Rossum12710051999-02-27 17:18:30 +0000324 self._creator = rv
325
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000326 def clicklinefield(self):
327 if self._currentwidget <> self.linefield:
328 self.linefield.select(1)
329 self.linefield.selectall()
330 return 1
331
332 def clickeditor(self):
333 if self._currentwidget <> self.editgroup.editor:
334 self.dolinefield()
335 return 1
336
337 def updateselection(self, force = 0):
338 sel = min(self.editgroup.editor.getselection())
339 lineno = self.editgroup.editor.offsettoline(sel)
340 if lineno <> self.lastlineno or force:
341 self.lastlineno = lineno
342 self.linefield.set(str(lineno + 1))
343 self.linefield.selview()
344
345 def dolinefield(self):
346 try:
347 lineno = string.atoi(self.linefield.get()) - 1
348 if lineno <> self.lastlineno:
349 self.editgroup.editor.selectline(lineno)
350 self.updateselection(1)
351 except:
352 self.updateselection(1)
353 self.editgroup.editor.select(1)
354
355 def setinfotext(self):
356 if not hasattr(self, 'infotext'):
357 return
358 if self.path:
359 self.infotext.set(self.path)
360 else:
361 self.infotext.set("")
362
363 def close(self):
364 if self.editgroup.editor.changed:
365 import EasyDialogs
Jack Jansen5a6fdcd2001-08-25 12:15:04 +0000366 from Carbon import Qd
Just van Rossum25ddc632001-07-05 07:06:26 +0000367 Qd.InitCursor()
368 save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title,
369 default=1, no="Don\xd5t save")
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000370 if save > 0:
371 if self.domenu_save():
372 return 1
373 elif save < 0:
374 return 1
Just van Rossum25ddc632001-07-05 07:06:26 +0000375 self.globals = None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000376 W.Window.close(self)
377
378 def domenu_close(self, *args):
379 return self.close()
380
381 def domenu_save(self, *args):
382 if not self.path:
383 # Will call us recursively
384 return self.domenu_save_as()
385 data = self.editgroup.editor.get()
386 fp = open(self.path, 'wb') # open file in binary mode, data has '\r' line-endings
387 fp.write(data)
388 fp.close()
389 fss = macfs.FSSpec(self.path)
390 fss.SetCreatorType(self._creator, 'TEXT')
391 self.getsettings()
392 self.writewindowsettings()
393 self.editgroup.editor.changed = 0
394 self.editgroup.editor.selchanged = 0
395 import linecache
396 if linecache.cache.has_key(self.path):
397 del linecache.cache[self.path]
398 import macostools
399 macostools.touched(self.path)
400
401 def can_save(self, menuitem):
402 return self.editgroup.editor.changed or self.editgroup.editor.selchanged
403
404 def domenu_save_as(self, *args):
405 fss, ok = macfs.StandardPutFile('Save as:', self.title)
406 if not ok:
407 return 1
408 self.showbreakpoints(0)
409 self.path = fss.as_pathname()
410 self.setinfotext()
411 self.title = os.path.split(self.path)[-1]
412 self.wid.SetWTitle(self.title)
413 self.domenu_save()
414 self.editgroup.editor.setfile(self.getfilename())
415 app = W.getapplication()
416 app.makeopenwindowsmenu()
417 if hasattr(app, 'makescriptsmenu'):
418 app = W.getapplication()
419 fss, fss_changed = app.scriptsfolder.Resolve()
420 path = fss.as_pathname()
421 if path == self.path[:len(path)]:
422 W.getapplication().makescriptsmenu()
423
424 def domenu_save_as_applet(self, *args):
Just van Rossumdc3c6172001-06-19 21:37:33 +0000425 import buildtools
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000426
427 buildtools.DEBUG = 0 # ouch.
428
429 if self.title[-3:] == ".py":
430 destname = self.title[:-3]
431 else:
432 destname = self.title + ".applet"
433 fss, ok = macfs.StandardPutFile('Save as Applet:', destname)
434 if not ok:
435 return 1
436 W.SetCursor("watch")
437 destname = fss.as_pathname()
438 if self.path:
439 filename = self.path
440 if filename[-3:] == ".py":
441 rsrcname = filename[:-3] + '.rsrc'
442 else:
443 rsrcname = filename + '.rsrc'
444 else:
445 filename = self.title
446 rsrcname = ""
447
448 pytext = self.editgroup.editor.get()
449 pytext = string.split(pytext, '\r')
450 pytext = string.join(pytext, '\n') + '\n'
451 try:
452 code = compile(pytext, filename, "exec")
453 except (SyntaxError, EOFError):
454 raise buildtools.BuildError, "Syntax error in script %s" % `filename`
455
456 # Try removing the output file
457 try:
458 os.remove(destname)
459 except os.error:
460 pass
461 template = buildtools.findtemplate()
462 buildtools.process_common(template, None, code, rsrcname, destname, 0, 1)
463
464 def domenu_gotoline(self, *args):
465 self.linefield.selectall()
466 self.linefield.select(1)
467 self.linefield.selectall()
468
469 def domenu_selectline(self, *args):
470 self.editgroup.editor.expandselection()
471
472 def domenu_find(self, *args):
473 searchengine.show()
474
475 def domenu_entersearchstring(self, *args):
476 searchengine.setfindstring()
477
478 def domenu_replace(self, *args):
479 searchengine.replace()
480
481 def domenu_findnext(self, *args):
482 searchengine.findnext()
483
484 def domenu_replacefind(self, *args):
485 searchengine.replacefind()
486
487 def domenu_run(self, *args):
488 self.runbutton.push()
489
490 def domenu_runselection(self, *args):
491 self.runselbutton.push()
492
493 def run(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000494 if self._threadstate == (0, 0):
495 self._run()
496 else:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000497 lock = Wthreading.Lock()
498 lock.acquire()
499 self._thread.postException(KeyboardInterrupt)
500 if self._thread.isBlocked():
Just van Rossum73efed22000-04-09 19:45:22 +0000501 self._thread.start()
Just van Rossum0f2fd162000-10-20 06:36:30 +0000502 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000503
504 def _run(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000505 if self.run_with_interpreter:
506 if self.editgroup.editor.changed:
507 import EasyDialogs
508 import Qd; Qd.InitCursor()
Just van Rossumdc3c6172001-06-19 21:37:33 +0000509 save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
Just van Rossum0f2fd162000-10-20 06:36:30 +0000510 if save > 0:
511 if self.domenu_save():
512 return
513 elif save < 0:
514 return
515 if not self.path:
516 raise W.AlertError, "Can't run unsaved file"
517 self._run_with_interpreter()
518 else:
519 pytext = self.editgroup.editor.get()
520 globals, file, modname = self.getenvironment()
521 self.execstring(pytext, globals, globals, file, modname)
522
523 def _run_with_interpreter(self):
524 interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
525 if not os.path.exists(interp_path):
526 raise W.AlertError, "Can't find interpreter"
527 import findertools
528 XXX
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000529
530 def runselection(self):
Just van Rossum73efed22000-04-09 19:45:22 +0000531 if self._threadstate == (0, 0):
532 self._runselection()
533 elif self._threadstate == (1, 1):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000534 self._thread.block()
Just van Rossum73efed22000-04-09 19:45:22 +0000535 self.setthreadstate((1, 2))
536 elif self._threadstate == (1, 2):
537 self._thread.start()
538 self.setthreadstate((1, 1))
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000539
540 def _runselection(self):
Just van Rossum0f2fd162000-10-20 06:36:30 +0000541 if self.run_with_interpreter:
542 raise W.AlertError, "Can't run selection with Interpreter"
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000543 globals, file, modname = self.getenvironment()
544 locals = globals
545 # select whole lines
546 self.editgroup.editor.expandselection()
547
548 # get lineno of first selected line
549 selstart, selend = self.editgroup.editor.getselection()
550 selstart, selend = min(selstart, selend), max(selstart, selend)
551 selfirstline = self.editgroup.editor.offsettoline(selstart)
552 alltext = self.editgroup.editor.get()
553 pytext = alltext[selstart:selend]
554 lines = string.split(pytext, '\r')
555 indent = getminindent(lines)
556 if indent == 1:
557 classname = ''
558 alllines = string.split(alltext, '\r')
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000559 for i in range(selfirstline - 1, -1, -1):
560 line = alllines[i]
561 if line[:6] == 'class ':
562 classname = string.split(string.strip(line[6:]))[0]
563 classend = identifieRE_match(classname)
564 if classend < 1:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000565 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000566 classname = classname[:classend]
567 break
568 elif line and line[0] not in '\t#':
Just van Rossumdc3c6172001-06-19 21:37:33 +0000569 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000570 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000571 raise W.AlertError, "Can't find a class."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000572 if globals.has_key(classname):
Just van Rossum25ddc632001-07-05 07:06:26 +0000573 klass = globals[classname]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000574 else:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000575 raise W.AlertError, "Can't find class \"%s\"." % classname
Just van Rossum25ddc632001-07-05 07:06:26 +0000576 # add class def
577 pytext = ("class %s:\n" % classname) + pytext
578 selfirstline = selfirstline - 1
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000579 elif indent > 0:
Just van Rossumdc3c6172001-06-19 21:37:33 +0000580 raise W.AlertError, "Can't run indented code."
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000581
582 # add "newlines" to fool compile/exec:
583 # now a traceback will give the right line number
584 pytext = selfirstline * '\r' + pytext
585 self.execstring(pytext, globals, locals, file, modname)
Just van Rossum25ddc632001-07-05 07:06:26 +0000586 if indent == 1 and globals[classname] is not klass:
587 # update the class in place
588 klass.__dict__.update(globals[classname].__dict__)
589 globals[classname] = klass
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000590
Just van Rossum73efed22000-04-09 19:45:22 +0000591 def setthreadstate(self, state):
592 oldstate = self._threadstate
593 if oldstate[0] <> state[0]:
594 self.runbutton.settitle(runButtonLabels[state[0]])
595 if oldstate[1] <> state[1]:
596 self.runselbutton.settitle(runSelButtonLabels[state[1]])
597 self._threadstate = state
598
599 def _exec_threadwrapper(self, *args, **kwargs):
600 apply(execstring, args, kwargs)
601 self.setthreadstate((0, 0))
602 self._thread = None
603
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000604 def execstring(self, pytext, globals, locals, file, modname):
605 tracebackwindow.hide()
606 # update windows
607 W.getapplication().refreshwindows()
608 if self.run_as_main:
609 modname = "__main__"
610 if self.path:
611 dir = os.path.dirname(self.path)
612 savedir = os.getcwd()
613 os.chdir(dir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000614 sys.path.insert(0, dir)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000615 else:
616 cwdindex = None
617 try:
Just van Rossum0f2fd162000-10-20 06:36:30 +0000618 if haveThreading:
619 self._thread = Wthreading.Thread(os.path.basename(file),
Just van Rossum73efed22000-04-09 19:45:22 +0000620 self._exec_threadwrapper, pytext, globals, locals, file, self.debugging,
621 modname, self.profiling)
622 self.setthreadstate((1, 1))
623 self._thread.start()
624 else:
625 execstring(pytext, globals, locals, file, self.debugging,
626 modname, self.profiling)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000627 finally:
628 if self.path:
629 os.chdir(savedir)
Just van Rossuma61f4ac1999-02-01 16:34:08 +0000630 del sys.path[0]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000631
632 def getenvironment(self):
633 if self.path:
634 file = self.path
635 dir = os.path.dirname(file)
636 # check if we're part of a package
637 modname = ""
638 while os.path.exists(os.path.join(dir, "__init__.py")):
639 dir, dirname = os.path.split(dir)
Just van Rossum2aaeb521999-02-05 21:58:25 +0000640 modname = dirname + '.' + modname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000641 subname = _filename_as_modname(self.title)
Just van Rossumf7f93882001-11-02 19:24:41 +0000642 if subname is None:
643 return self.globals, file, None
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000644 if modname:
645 if subname == "__init__":
Just van Rossum2aaeb521999-02-05 21:58:25 +0000646 # strip trailing period
647 modname = modname[:-1]
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000648 else:
Just van Rossum2aaeb521999-02-05 21:58:25 +0000649 modname = modname + subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000650 else:
651 modname = subname
652 if sys.modules.has_key(modname):
653 globals = sys.modules[modname].__dict__
654 self.globals = {}
655 else:
656 globals = self.globals
Just van Rossum73efed22000-04-09 19:45:22 +0000657 modname = subname
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000658 else:
659 file = '<%s>' % self.title
660 globals = self.globals
661 modname = file
662 return globals, file, modname
663
664 def write(self, stuff):
665 """for use as stdout"""
666 self._buf = self._buf + stuff
667 if '\n' in self._buf:
668 self.flush()
669
670 def flush(self):
671 stuff = string.split(self._buf, '\n')
672 stuff = string.join(stuff, '\r')
673 end = self.editgroup.editor.ted.WEGetTextLength()
674 self.editgroup.editor.ted.WESetSelection(end, end)
675 self.editgroup.editor.ted.WEInsert(stuff, None, None)
676 self.editgroup.editor.updatescrollbars()
677 self._buf = ""
678 # ? optional:
679 #self.wid.SelectWindow()
680
681 def getclasslist(self):
682 from string import find, strip
Just van Rossum24073ea1999-12-23 15:46:57 +0000683 methodRE = re.compile(r"\r[ \t]+def ")
684 findMethod = methodRE.search
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000685 editor = self.editgroup.editor
686 text = editor.get()
687 list = []
688 append = list.append
689 functag = "func"
690 classtag = "class"
691 methodtag = "method"
692 pos = -1
693 if text[:4] == 'def ':
694 append((pos + 4, functag))
695 pos = 4
696 while 1:
697 pos = find(text, '\rdef ', pos + 1)
698 if pos < 0:
699 break
700 append((pos + 5, functag))
701 pos = -1
702 if text[:6] == 'class ':
703 append((pos + 6, classtag))
704 pos = 6
705 while 1:
706 pos = find(text, '\rclass ', pos + 1)
707 if pos < 0:
708 break
709 append((pos + 7, classtag))
710 pos = 0
711 while 1:
Just van Rossum24073ea1999-12-23 15:46:57 +0000712 m = findMethod(text, pos + 1)
713 if m is None:
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000714 break
Just van Rossum24073ea1999-12-23 15:46:57 +0000715 pos = m.regs[0][0]
716 #pos = find(text, '\r\tdef ', pos + 1)
717 append((m.regs[0][1], methodtag))
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000718 list.sort()
719 classlist = []
720 methodlistappend = None
721 offsetToLine = editor.ted.WEOffsetToLine
722 getLineRange = editor.ted.WEGetLineRange
723 append = classlist.append
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000724 for pos, tag in list:
725 lineno = offsetToLine(pos)
726 lineStart, lineEnd = getLineRange(lineno)
727 line = strip(text[pos:lineEnd])
728 line = line[:identifieRE_match(line)]
729 if tag is functag:
730 append(("def " + line, lineno + 1))
731 methodlistappend = None
732 elif tag is classtag:
733 append(["class " + line])
734 methodlistappend = classlist[-1].append
735 elif methodlistappend and tag is methodtag:
736 methodlistappend(("def " + line, lineno + 1))
737 return classlist
738
739 def popselectline(self, lineno):
740 self.editgroup.editor.selectline(lineno - 1)
741
742 def selectline(self, lineno, charoffset = 0):
743 self.editgroup.editor.selectline(lineno - 1, charoffset)
744
Just van Rossum12710051999-02-27 17:18:30 +0000745class _saveoptions:
746
747 def __init__(self, creator):
748 self.rv = None
749 self.w = w = W.ModalDialog((240, 140), 'Save options')
750 radiobuttons = []
751 w.label = W.TextBox((8, 8, 80, 18), "File creator:")
Just van Rossum3af507d1999-04-22 22:23:46 +0000752 w.ide_radio = W.RadioButton((8, 22, 160, 18), "This application", radiobuttons, self.ide_hit)
753 w.interp_radio = W.RadioButton((8, 42, 160, 18), "Python Interpreter", radiobuttons, self.interp_hit)
Just van Rossum12710051999-02-27 17:18:30 +0000754 w.other_radio = W.RadioButton((8, 62, 50, 18), "Other:", radiobuttons)
755 w.other_creator = W.EditText((62, 62, 40, 20), creator, self.otherselect)
756 w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
757 w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
758 w.setdefaultbutton(w.okbutton)
759 if creator == 'Pyth':
760 w.interp_radio.set(1)
Just van Rossum3af507d1999-04-22 22:23:46 +0000761 elif creator == W._signature:
Just van Rossum12710051999-02-27 17:18:30 +0000762 w.ide_radio.set(1)
763 else:
764 w.other_radio.set(1)
765 w.bind("cmd.", w.cancelbutton.push)
766 w.open()
767
768 def ide_hit(self):
Just van Rossum3af507d1999-04-22 22:23:46 +0000769 self.w.other_creator.set(W._signature)
Just van Rossum12710051999-02-27 17:18:30 +0000770
771 def interp_hit(self):
772 self.w.other_creator.set("Pyth")
773
774 def otherselect(self, *args):
775 sel_from, sel_to = self.w.other_creator.getselection()
776 creator = self.w.other_creator.get()[:4]
777 creator = creator + " " * (4 - len(creator))
778 self.w.other_creator.set(creator)
779 self.w.other_creator.setselection(sel_from, sel_to)
780 self.w.other_radio.set(1)
781
782 def cancelbuttonhit(self):
783 self.w.close()
784
785 def okbuttonhit(self):
786 self.rv = self.w.other_creator.get()[:4]
787 self.w.close()
788
789
790def SaveOptions(creator):
791 s = _saveoptions(creator)
792 return s.rv
793
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000794
795def _escape(where, what) :
796 return string.join(string.split(where, what), '\\' + what)
797
798def _makewholewordpattern(word):
799 # first, escape special regex chars
Just van Rossum3eec7622001-07-10 19:25:40 +0000800 for esc in "\\[]()|.*^+$?":
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000801 word = _escape(word, esc)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000802 notwordcharspat = '[^' + _wordchars + ']'
Jack Jansen9ad27522001-02-21 13:54:31 +0000803 pattern = '(' + word + ')'
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000804 if word[0] in _wordchars:
805 pattern = notwordcharspat + pattern
806 if word[-1] in _wordchars:
807 pattern = pattern + notwordcharspat
Jack Jansen9ad27522001-02-21 13:54:31 +0000808 return re.compile(pattern)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000809
Just van Rossumf376ef02001-11-18 14:12:43 +0000810
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000811class SearchEngine:
812
813 def __init__(self):
814 self.visible = 0
815 self.w = None
816 self.parms = { "find": "",
817 "replace": "",
818 "wrap": 1,
819 "casesens": 1,
820 "wholeword": 1
821 }
822 import MacPrefs
823 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
824 if prefs.searchengine:
825 self.parms["casesens"] = prefs.searchengine.casesens
826 self.parms["wrap"] = prefs.searchengine.wrap
827 self.parms["wholeword"] = prefs.searchengine.wholeword
828
829 def show(self):
830 self.visible = 1
831 if self.w:
832 self.w.wid.ShowWindow()
833 self.w.wid.SelectWindow()
834 self.w.find.edit.select(1)
835 self.w.find.edit.selectall()
836 return
837 self.w = W.Dialog((420, 150), "Find")
838
839 self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
840 self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
841
842 self.w.boxes = W.Group((10, 50, 300, 40))
843 self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
844 self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
845 self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
846
847 self.buttons = [ ("Find", "cmdf", self.find),
848 ("Replace", "cmdr", self.replace),
849 ("Replace all", None, self.replaceall),
Just van Rossumdc3c6172001-06-19 21:37:33 +0000850 ("Don't find", "cmdd", self.dont),
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000851 ("Cancel", "cmd.", self.cancel)
852 ]
853 for i in range(len(self.buttons)):
854 bounds = -90, 22 + i * 24, 80, 16
855 title, shortcut, callback = self.buttons[i]
856 self.w[title] = W.Button(bounds, title, callback)
857 if shortcut:
858 self.w.bind(shortcut, self.w[title].push)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000859 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000860 self.w.find.edit.bind("<key>", self.key)
861 self.w.bind("<activate>", self.activate)
862 self.w.bind("<close>", self.close)
863 self.w.open()
864 self.setparms()
865 self.w.find.edit.select(1)
866 self.w.find.edit.selectall()
867 self.checkbuttons()
868
869 def close(self):
870 self.hide()
871 return -1
872
873 def key(self, char, modifiers):
874 self.w.find.edit.key(char, modifiers)
875 self.checkbuttons()
876 return 1
877
878 def activate(self, onoff):
879 if onoff:
880 self.checkbuttons()
881
882 def checkbuttons(self):
883 editor = findeditor(self)
884 if editor:
885 if self.w.find.get():
886 for title, cmd, call in self.buttons[:-2]:
887 self.w[title].enable(1)
888 self.w.setdefaultbutton(self.w["Find"])
889 else:
890 for title, cmd, call in self.buttons[:-2]:
891 self.w[title].enable(0)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000892 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000893 else:
894 for title, cmd, call in self.buttons[:-2]:
895 self.w[title].enable(0)
Just van Rossumdc3c6172001-06-19 21:37:33 +0000896 self.w.setdefaultbutton(self.w["Don't find"])
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000897
898 def find(self):
899 self.getparmsfromwindow()
900 if self.findnext():
901 self.hide()
902
903 def replace(self):
904 editor = findeditor(self)
905 if not editor:
906 return
907 if self.visible:
908 self.getparmsfromwindow()
909 text = editor.getselectedtext()
910 find = self.parms["find"]
911 if not self.parms["casesens"]:
912 find = string.lower(find)
913 text = string.lower(text)
914 if text == find:
915 self.hide()
916 editor.insert(self.parms["replace"])
917
918 def replaceall(self):
919 editor = findeditor(self)
920 if not editor:
921 return
922 if self.visible:
923 self.getparmsfromwindow()
924 W.SetCursor("watch")
925 find = self.parms["find"]
926 if not find:
927 return
928 findlen = len(find)
929 replace = self.parms["replace"]
930 replacelen = len(replace)
931 Text = editor.get()
932 if not self.parms["casesens"]:
933 find = string.lower(find)
934 text = string.lower(Text)
935 else:
936 text = Text
937 newtext = ""
938 pos = 0
939 counter = 0
940 while 1:
941 if self.parms["wholeword"]:
942 wholewordRE = _makewholewordpattern(find)
Jack Jansen9ad27522001-02-21 13:54:31 +0000943 match = wholewordRE.search(text, pos)
944 if match:
945 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000946 else:
947 pos = -1
948 else:
949 pos = string.find(text, find, pos)
950 if pos < 0:
951 break
952 counter = counter + 1
953 text = text[:pos] + replace + text[pos + findlen:]
954 Text = Text[:pos] + replace + Text[pos + findlen:]
955 pos = pos + replacelen
956 W.SetCursor("arrow")
957 if counter:
958 self.hide()
959 import EasyDialogs
Jack Jansen5a6fdcd2001-08-25 12:15:04 +0000960 from Carbon import Res
Just van Rossumf7f93882001-11-02 19:24:41 +0000961 editor.textchanged()
962 editor.selectionchanged()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000963 editor.ted.WEUseText(Res.Resource(Text))
964 editor.ted.WECalText()
965 editor.SetPort()
Jack Jansen73023402001-01-23 14:58:20 +0000966 editor.GetWindow().InvalWindowRect(editor._bounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000967 #editor.ted.WEUpdate(self.w.wid.GetWindowPort().visRgn)
968 EasyDialogs.Message("Replaced %d occurrences" % counter)
969
970 def dont(self):
971 self.getparmsfromwindow()
972 self.hide()
973
974 def replacefind(self):
975 self.replace()
976 self.findnext()
977
978 def setfindstring(self):
979 editor = findeditor(self)
980 if not editor:
981 return
982 find = editor.getselectedtext()
983 if not find:
984 return
985 self.parms["find"] = find
986 if self.w:
987 self.w.find.edit.set(self.parms["find"])
988 self.w.find.edit.selectall()
989
990 def findnext(self):
991 editor = findeditor(self)
992 if not editor:
993 return
994 find = self.parms["find"]
995 if not find:
996 return
997 text = editor.get()
998 if not self.parms["casesens"]:
999 find = string.lower(find)
1000 text = string.lower(text)
1001 selstart, selend = editor.getselection()
1002 selstart, selend = min(selstart, selend), max(selstart, selend)
1003 if self.parms["wholeword"]:
1004 wholewordRE = _makewholewordpattern(find)
Jack Jansen9ad27522001-02-21 13:54:31 +00001005 match = wholewordRE.search(text, selend)
1006 if match:
1007 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001008 else:
1009 pos = -1
1010 else:
1011 pos = string.find(text, find, selend)
1012 if pos >= 0:
1013 editor.setselection(pos, pos + len(find))
1014 return 1
1015 elif self.parms["wrap"]:
1016 if self.parms["wholeword"]:
Jack Jansen9ad27522001-02-21 13:54:31 +00001017 match = wholewordRE.search(text, 0)
1018 if match:
1019 pos = match.start(1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001020 else:
1021 pos = -1
1022 else:
1023 pos = string.find(text, find)
1024 if selstart > pos >= 0:
1025 editor.setselection(pos, pos + len(find))
1026 return 1
1027
1028 def setparms(self):
1029 for key, value in self.parms.items():
1030 try:
1031 self.w[key].set(value)
1032 except KeyError:
1033 self.w.boxes[key].set(value)
1034
1035 def getparmsfromwindow(self):
1036 if not self.w:
1037 return
1038 for key, value in self.parms.items():
1039 try:
1040 value = self.w[key].get()
1041 except KeyError:
1042 value = self.w.boxes[key].get()
1043 self.parms[key] = value
1044
1045 def cancel(self):
1046 self.hide()
1047 self.setparms()
1048
1049 def hide(self):
1050 if self.w:
1051 self.w.wid.HideWindow()
1052 self.visible = 0
1053
1054 def writeprefs(self):
1055 import MacPrefs
1056 self.getparmsfromwindow()
1057 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1058 prefs.searchengine.casesens = self.parms["casesens"]
1059 prefs.searchengine.wrap = self.parms["wrap"]
1060 prefs.searchengine.wholeword = self.parms["wholeword"]
1061 prefs.save()
1062
1063
1064class TitledEditText(W.Group):
1065
1066 def __init__(self, possize, title, text = ""):
1067 W.Group.__init__(self, possize)
1068 self.title = W.TextBox((0, 0, 0, 16), title)
1069 self.edit = W.EditText((0, 16, 0, 0), text)
1070
1071 def set(self, value):
1072 self.edit.set(value)
1073
1074 def get(self):
1075 return self.edit.get()
1076
1077
1078class ClassFinder(W.PopupWidget):
1079
1080 def click(self, point, modifiers):
1081 W.SetCursor("watch")
1082 self.set(self._parentwindow.getclasslist())
1083 W.PopupWidget.click(self, point, modifiers)
1084
1085
1086def getminindent(lines):
1087 indent = -1
1088 for line in lines:
1089 stripped = string.strip(line)
1090 if not stripped or stripped[0] == '#':
1091 continue
1092 if indent < 0 or line[:indent] <> indent * '\t':
1093 indent = 0
1094 for c in line:
1095 if c <> '\t':
1096 break
1097 indent = indent + 1
1098 return indent
1099
1100
1101def getoptionkey():
1102 return not not ord(Evt.GetKeys()[7]) & 0x04
1103
1104
1105def execstring(pytext, globals, locals, filename="<string>", debugging=0,
1106 modname="__main__", profiling=0):
1107 if debugging:
1108 import PyDebugger, bdb
1109 BdbQuit = bdb.BdbQuit
1110 else:
1111 BdbQuit = 'BdbQuitDummyException'
1112 pytext = string.split(pytext, '\r')
1113 pytext = string.join(pytext, '\n') + '\n'
1114 W.SetCursor("watch")
1115 globals['__name__'] = modname
1116 globals['__file__'] = filename
1117 sys.argv = [filename]
1118 try:
1119 code = compile(pytext, filename, "exec")
1120 except:
1121 # XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError
1122 # special. That's wrong because THIS case is special (could be literal
1123 # overflow!) and SyntaxError could mean we need a traceback (syntax error
1124 # in imported module!!!
1125 tracebackwindow.traceback(1, filename)
1126 return
1127 try:
1128 if debugging:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001129 if haveThreading:
1130 lock = Wthreading.Lock()
1131 lock.acquire()
Just van Rossum73efed22000-04-09 19:45:22 +00001132 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001133 lock.release()
Just van Rossum73efed22000-04-09 19:45:22 +00001134 else:
1135 PyDebugger.startfromhere()
Just van Rossum0f2fd162000-10-20 06:36:30 +00001136 elif not haveThreading:
Jack Jansen815d2bf2002-01-21 23:00:52 +00001137 if hasattr(MacOS, 'EnableAppswitch'):
1138 MacOS.EnableAppswitch(0)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001139 try:
1140 if profiling:
1141 import profile, ProfileBrowser
1142 p = profile.Profile()
1143 p.set_cmd(filename)
1144 try:
1145 p.runctx(code, globals, locals)
1146 finally:
1147 import pstats
1148
1149 stats = pstats.Stats(p)
1150 ProfileBrowser.ProfileBrowser(stats)
1151 else:
1152 exec code in globals, locals
1153 finally:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001154 if not haveThreading:
Jack Jansen815d2bf2002-01-21 23:00:52 +00001155 if hasattr(MacOS, 'EnableAppswitch'):
1156 MacOS.EnableAppswitch(-1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001157 except W.AlertError, detail:
1158 raise W.AlertError, detail
1159 except (KeyboardInterrupt, BdbQuit):
1160 pass
Just van Rossumf7f93882001-11-02 19:24:41 +00001161 except SystemExit, arg:
1162 if arg.code:
1163 sys.stderr.write("Script exited with status code: %s\n" % repr(arg.code))
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001164 except:
Just van Rossum0f2fd162000-10-20 06:36:30 +00001165 if haveThreading:
1166 import continuation
1167 lock = Wthreading.Lock()
1168 lock.acquire()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001169 if debugging:
1170 sys.settrace(None)
1171 PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
1172 return
1173 else:
1174 tracebackwindow.traceback(1, filename)
Just van Rossum0f2fd162000-10-20 06:36:30 +00001175 if haveThreading:
1176 lock.release()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001177 if debugging:
1178 sys.settrace(None)
1179 PyDebugger.stop()
1180
1181
Just van Rossum3eec7622001-07-10 19:25:40 +00001182_identifieRE = re.compile(r"[A-Za-z_][A-Za-z_0-9]*")
Jack Jansen9ad27522001-02-21 13:54:31 +00001183
1184def identifieRE_match(str):
1185 match = _identifieRE.match(str)
1186 if not match:
1187 return -1
1188 return match.end()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001189
1190def _filename_as_modname(fname):
1191 if fname[-3:] == '.py':
1192 modname = fname[:-3]
Jack Jansen9ad27522001-02-21 13:54:31 +00001193 match = _identifieRE.match(modname)
1194 if match and match.start() == 0 and match.end() == len(modname):
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001195 return string.join(string.split(modname, '.'), '_')
1196
1197def findeditor(topwindow, fromtop = 0):
Just van Rossum40144012002-02-04 12:52:44 +00001198 wid = MyFrontWindow()
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001199 if not fromtop:
1200 if topwindow.w and wid == topwindow.w.wid:
1201 wid = topwindow.w.wid.GetNextWindow()
1202 if not wid:
1203 return
1204 app = W.getapplication()
1205 if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
1206 window = W.getapplication()._windows[wid]
1207 else:
1208 return
1209 if not isinstance(window, Editor):
1210 return
1211 return window.editgroup.editor
1212
1213
1214class _EditorDefaultSettings:
1215
1216 def __init__(self):
1217 self.template = "%s, %d point"
1218 self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
1219 self.w = W.Dialog((328, 120), "Editor default settings")
Just van Rossumdc3c6172001-06-19 21:37:33 +00001220 self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont)
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001221 self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
1222
1223 self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
1224 self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
1225 self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
1226 self.w.xsize = W.EditText((98, 48, 40, 20), `self.windowsize[0]`)
1227 self.w.ysize = W.EditText((148, 48, 40, 20), `self.windowsize[1]`)
1228
1229 self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
1230 self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
1231 self.w.setdefaultbutton(self.w.okbutton)
1232 self.w.bind('cmd.', self.w.cancelbutton.push)
1233 self.w.open()
1234
1235 def picksize(self):
1236 app = W.getapplication()
1237 editor = findeditor(self)
1238 if editor is not None:
1239 width, height = editor._parentwindow._bounds[2:]
1240 self.w.xsize.set(`width`)
1241 self.w.ysize.set(`height`)
1242 else:
1243 raise W.AlertError, "No edit window found"
1244
1245 def dofont(self):
1246 import FontSettings
1247 settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
1248 if settings:
1249 self.fontsettings, self.tabsettings = settings
1250 sys.exc_traceback = None
1251 self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
1252
1253 def close(self):
1254 self.w.close()
1255 del self.w
1256
1257 def cancel(self):
1258 self.close()
1259
1260 def ok(self):
1261 try:
1262 width = string.atoi(self.w.xsize.get())
1263 except:
1264 self.w.xsize.select(1)
1265 self.w.xsize.selectall()
1266 raise W.AlertError, "Bad number for window width"
1267 try:
1268 height = string.atoi(self.w.ysize.get())
1269 except:
1270 self.w.ysize.select(1)
1271 self.w.ysize.selectall()
1272 raise W.AlertError, "Bad number for window height"
1273 self.windowsize = width, height
1274 seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
1275 self.close()
1276
1277def geteditorprefs():
1278 import MacPrefs
1279 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1280 try:
1281 fontsettings = prefs.pyedit.fontsettings
1282 tabsettings = prefs.pyedit.tabsettings
1283 windowsize = prefs.pyedit.windowsize
1284 except:
Just van Rossumf7f93882001-11-02 19:24:41 +00001285 fontsettings = prefs.pyedit.fontsettings = ("Geneva", 0, 10, (0, 0, 0))
Just van Rossum40f9b7b1999-01-30 22:39:17 +00001286 tabsettings = prefs.pyedit.tabsettings = (8, 1)
1287 windowsize = prefs.pyedit.windowsize = (500, 250)
1288 sys.exc_traceback = None
1289 return fontsettings, tabsettings, windowsize
1290
1291def seteditorprefs(fontsettings, tabsettings, windowsize):
1292 import MacPrefs
1293 prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
1294 prefs.pyedit.fontsettings = fontsettings
1295 prefs.pyedit.tabsettings = tabsettings
1296 prefs.pyedit.windowsize = windowsize
1297 prefs.save()
1298
1299_defaultSettingsEditor = None
1300
1301def EditorDefaultSettings():
1302 global _defaultSettingsEditor
1303 if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
1304 _defaultSettingsEditor = _EditorDefaultSettings()
1305 else:
1306 _defaultSettingsEditor.w.select()
1307
1308def resolvealiases(path):
1309 try:
1310 return macfs.ResolveAliasFile(path)[0].as_pathname()
1311 except (macfs.error, ValueError), (error, str):
1312 if error <> -120:
1313 raise
1314 dir, file = os.path.split(path)
1315 return os.path.join(resolvealiases(dir), file)
1316
1317searchengine = SearchEngine()
1318tracebackwindow = Wtraceback.TraceBack()