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