381 lines
11 KiB
Python
381 lines
11 KiB
Python
import W
|
||
import Wkeys
|
||
import Fm
|
||
import WASTEconst
|
||
from types import *
|
||
import Events
|
||
import string
|
||
import sys
|
||
import traceback
|
||
import MacOS
|
||
import MacPrefs
|
||
import Qd
|
||
import PyInteractive
|
||
|
||
if not hasattr(sys, 'ps1'):
|
||
sys.ps1 = '>>> '
|
||
if not hasattr(sys, 'ps2'):
|
||
sys.ps2 = '... '
|
||
|
||
def inspect(foo): # JJS 1/25/99
|
||
"Launch the browser on the given object. This is a general built-in function."
|
||
import PyBrowser
|
||
PyBrowser.Browser(foo)
|
||
|
||
class ConsoleTextWidget(W.EditText):
|
||
|
||
def __init__(self, *args, **kwargs):
|
||
apply(W.EditText.__init__, (self,) + args, kwargs)
|
||
self._inputstart = 0
|
||
self._buf = ''
|
||
self.pyinteractive = PyInteractive.PyInteractive()
|
||
|
||
import __main__
|
||
self._namespace = __main__.__dict__
|
||
self._namespace['inspect'] = inspect # JJS 1/25/99
|
||
|
||
def insert(self, text):
|
||
self.checkselection()
|
||
self.ted.WEInsert(text, None, None)
|
||
self.changed = 1
|
||
self.selchanged = 1
|
||
|
||
def set_namespace(self, dict):
|
||
if type(dict) <> DictionaryType:
|
||
raise TypeError, "The namespace needs to be a dictionary"
|
||
if 'inspect' not in dict.keys(): dict['inspect'] = inspect # JJS 1/25/99
|
||
self._namespace = dict
|
||
|
||
def open(self):
|
||
W.EditText.open(self)
|
||
self.write('Python ' + sys.version + '\n' + sys.copyright + '\n')
|
||
self.write(sys.ps1)
|
||
self.flush()
|
||
|
||
def key(self, char, event):
|
||
(what, message, when, where, modifiers) = event
|
||
if self._enabled and not modifiers & Events.cmdKey or char in Wkeys.arrowkeys:
|
||
if char not in Wkeys.navigationkeys:
|
||
self.checkselection()
|
||
if char == Wkeys.enterkey:
|
||
char = Wkeys.returnkey
|
||
selstart, selend = self.getselection()
|
||
if char == Wkeys.backspacekey:
|
||
if selstart <= (self._inputstart - (selstart <> selend)):
|
||
return
|
||
self.ted.WEKey(ord(char), modifiers)
|
||
if char not in Wkeys.navigationkeys:
|
||
self.changed = 1
|
||
if char not in Wkeys.scrollkeys:
|
||
self.selchanged = 1
|
||
self.updatescrollbars()
|
||
if char == Wkeys.returnkey:
|
||
text = self.get()[self._inputstart:selstart]
|
||
text = string.join(string.split(text, "\r"), "\n")
|
||
saveyield = MacOS.EnableAppswitch(0)
|
||
self.pyinteractive.executeline(text, self, self._namespace)
|
||
MacOS.EnableAppswitch(saveyield)
|
||
selstart, selend = self.getselection()
|
||
self._inputstart = selstart
|
||
|
||
def domenu_save_as(self, *args):
|
||
import macfs
|
||
fss, ok = macfs.StandardPutFile('Save console text as:', 'console.txt')
|
||
if not ok:
|
||
return
|
||
f = open(fss.as_pathname(), 'wb')
|
||
f.write(self.get())
|
||
f.close()
|
||
fss.SetCreatorType(W._signature, 'TEXT')
|
||
|
||
def write(self, text):
|
||
self._buf = self._buf + text
|
||
if '\n' in self._buf:
|
||
self.flush()
|
||
|
||
def flush(self):
|
||
stuff = string.split(self._buf, '\n')
|
||
stuff = string.join(stuff, '\r')
|
||
self.setselection_at_end()
|
||
self.ted.WEInsert(stuff, None, None)
|
||
selstart, selend = self.getselection()
|
||
self._inputstart = selstart
|
||
self._buf = ""
|
||
self.ted.WEClearUndo()
|
||
self.updatescrollbars()
|
||
|
||
def selection_ok(self):
|
||
selstart, selend = self.getselection()
|
||
return not (selstart < self._inputstart or selend < self._inputstart)
|
||
|
||
def checkselection(self):
|
||
if not self.selection_ok():
|
||
self.setselection_at_end()
|
||
|
||
def setselection_at_end(self):
|
||
end = self.ted.WEGetTextLength()
|
||
self.setselection(end, end)
|
||
self.updatescrollbars()
|
||
|
||
def domenu_cut(self, *args):
|
||
if not self.selection_ok():
|
||
return
|
||
W.EditText.domenu_cut(self)
|
||
|
||
def domenu_paste(self, *args):
|
||
if not self.selection_ok():
|
||
self.setselection_at_end()
|
||
W.EditText.domenu_paste(self)
|
||
|
||
def domenu_clear(self, *args):
|
||
if not self.selection_ok():
|
||
return
|
||
W.EditText.domenu_clear(self)
|
||
|
||
|
||
class PyConsole(W.Window):
|
||
|
||
def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)),
|
||
tabsettings = (32, 0), unclosable = 0):
|
||
W.Window.__init__(self,
|
||
bounds,
|
||
"Python Interactive",
|
||
minsize = (200, 100),
|
||
tabbable = 0,
|
||
show = show)
|
||
|
||
self._unclosable = unclosable
|
||
consoletext = ConsoleTextWidget((-1, -1, -14, 1), inset = (6, 5),
|
||
fontsettings = fontsettings, tabsettings = tabsettings)
|
||
self._bary = W.Scrollbar((-15, 14, 16, -14), consoletext.vscroll, max = 32767)
|
||
self.consoletext = consoletext
|
||
self.namespacemenu = W.PopupMenu((-15, -1, 16, 16), [], self.consoletext.set_namespace)
|
||
self.namespacemenu.bind('<click>', self.makenamespacemenu)
|
||
self.open()
|
||
|
||
def makenamespacemenu(self, *args):
|
||
W.SetCursor('watch')
|
||
namespacelist = self.getnamespacelist()
|
||
self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings<67>", self.dofontsettings),
|
||
["Namespace"] + namespacelist, ("Browse namespace<63>", self.browsenamespace)])
|
||
currentname = self.consoletext._namespace["__name__"]
|
||
for i in range(len(namespacelist)):
|
||
if namespacelist[i][0] == currentname:
|
||
break
|
||
else:
|
||
return
|
||
# XXX this functionality should be generally available in Wmenus
|
||
submenuid = self.namespacemenu.menu.menu.GetItemMark(3)
|
||
menu = self.namespacemenu.menu.bar.menus[submenuid]
|
||
menu.menu.CheckItem(i + 1, 1)
|
||
|
||
def browsenamespace(self):
|
||
import PyBrowser, W
|
||
W.SetCursor('watch')
|
||
PyBrowser.Browser(self.consoletext._namespace, self.consoletext._namespace["__name__"])
|
||
|
||
def clearbuffer(self):
|
||
import Res
|
||
self.consoletext.ted.WEUseText(Res.Resource(''))
|
||
self.consoletext.write(sys.ps1)
|
||
self.consoletext.flush()
|
||
|
||
def getnamespacelist(self):
|
||
import os
|
||
import __main__
|
||
editors = filter(lambda x: x.__class__.__name__ == "Editor", self.parent._windows.values())
|
||
|
||
namespaces = [ ("__main__",__main__.__dict__) ]
|
||
for ed in editors:
|
||
modname = os.path.splitext(ed.title)[0]
|
||
if sys.modules.has_key(modname):
|
||
module = sys.modules[modname]
|
||
namespaces.append((modname, module.__dict__))
|
||
else:
|
||
if ed.title[-3:] == '.py':
|
||
modname = ed.title[:-3]
|
||
else:
|
||
modname = ed.title
|
||
ed.globals["__name__"] = modname
|
||
namespaces.append((modname, ed.globals))
|
||
return namespaces
|
||
|
||
def dofontsettings(self):
|
||
import FontSettings
|
||
settings = FontSettings.FontDialog(self.consoletext.getfontsettings(),
|
||
self.consoletext.gettabsettings())
|
||
if settings:
|
||
fontsettings, tabsettings = settings
|
||
self.consoletext.setfontsettings(fontsettings)
|
||
self.consoletext.settabsettings(tabsettings)
|
||
|
||
def show(self, onoff = 1):
|
||
W.Window.show(self, onoff)
|
||
if onoff:
|
||
self.select()
|
||
|
||
def close(self):
|
||
if self._unclosable:
|
||
self.show(0)
|
||
return -1
|
||
W.Window.close(self)
|
||
|
||
def writeprefs(self):
|
||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
||
prefs.console.show = self.isvisible()
|
||
prefs.console.windowbounds = self.getbounds()
|
||
prefs.console.fontsettings = self.consoletext.getfontsettings()
|
||
prefs.console.tabsettings = self.consoletext.gettabsettings()
|
||
prefs.save()
|
||
|
||
|
||
class OutputTextWidget(W.EditText):
|
||
|
||
def domenu_save_as(self, *args):
|
||
title = self._parentwindow.gettitle()
|
||
import macfs
|
||
fss, ok = macfs.StandardPutFile('Save %s text as:' % title, title + '.txt')
|
||
if not ok:
|
||
return
|
||
f = open(fss.as_pathname(), 'wb')
|
||
f.write(self.get())
|
||
f.close()
|
||
fss.SetCreatorType(W._signature, 'TEXT')
|
||
|
||
|
||
class PyOutput:
|
||
|
||
def __init__(self, bounds, show = 1, fontsettings = ("Monaco", 0, 9, (0, 0, 0)), tabsettings = (32, 0)):
|
||
self.bounds = bounds
|
||
self.fontsettings = fontsettings
|
||
self.tabsettings = tabsettings
|
||
self.w = None
|
||
self.closed = 1
|
||
self._buf = ''
|
||
# should be able to set this
|
||
self.savestdout, self.savestderr = sys.stdout, sys.stderr
|
||
sys.stderr = sys.stdout = self
|
||
if show:
|
||
self.show()
|
||
|
||
def setupwidgets(self):
|
||
self.w = W.Window(self.bounds, "Output",
|
||
minsize = (200, 100),
|
||
tabbable = 0)
|
||
self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5),
|
||
fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1)
|
||
menuitems = [("Clear window", self.clearbuffer), ("Font settings<67>", self.dofontsettings)]
|
||
self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems)
|
||
|
||
self.w._bary = W.Scrollbar((-15, 14, 16, -14), self.w.outputtext.vscroll, max = 32767)
|
||
self.w.bind("<close>", self.close)
|
||
self.w.bind("<activate>", self.activate)
|
||
|
||
def write(self, text):
|
||
oldyield = MacOS.EnableAppswitch(-1)
|
||
try:
|
||
self._buf = self._buf + text
|
||
if '\n' in self._buf:
|
||
self.flush()
|
||
finally:
|
||
MacOS.EnableAppswitch(oldyield)
|
||
|
||
def flush(self):
|
||
self.show()
|
||
stuff = string.split(self._buf, '\n')
|
||
stuff = string.join(stuff, '\r')
|
||
end = self.w.outputtext.ted.WEGetTextLength()
|
||
self.w.outputtext.setselection(end, end)
|
||
self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 0)
|
||
self.w.outputtext.ted.WEInsert(stuff, None, None)
|
||
self._buf = ""
|
||
self.w.outputtext.updatescrollbars()
|
||
self.w.outputtext.ted.WEFeatureFlag(WASTEconst.weFReadOnly, 1)
|
||
|
||
def show(self):
|
||
if self.closed:
|
||
if not self.w:
|
||
self.setupwidgets()
|
||
self.w.open()
|
||
self.w.outputtext.updatescrollbars()
|
||
self.closed = 0
|
||
else:
|
||
self.w.show(1)
|
||
self.closed = 0
|
||
self.w.select()
|
||
|
||
def writeprefs(self):
|
||
if self.w is not None:
|
||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
||
prefs.output.show = self.w.isvisible()
|
||
prefs.output.windowbounds = self.w.getbounds()
|
||
prefs.output.fontsettings = self.w.outputtext.getfontsettings()
|
||
prefs.output.tabsettings = self.w.outputtext.gettabsettings()
|
||
prefs.save()
|
||
|
||
def dofontsettings(self):
|
||
import FontSettings
|
||
settings = FontSettings.FontDialog(self.w.outputtext.getfontsettings(),
|
||
self.w.outputtext.gettabsettings())
|
||
if settings:
|
||
fontsettings, tabsettings = settings
|
||
self.w.outputtext.setfontsettings(fontsettings)
|
||
self.w.outputtext.settabsettings(tabsettings)
|
||
|
||
def clearbuffer(self):
|
||
import Res
|
||
self.w.outputtext.set('')
|
||
|
||
def activate(self, onoff):
|
||
if onoff:
|
||
self.closed = 0
|
||
|
||
def close(self):
|
||
self.w.show(0)
|
||
self.closed = 1
|
||
return -1
|
||
|
||
|
||
class SimpleStdin:
|
||
|
||
def readline(self):
|
||
import EasyDialogs
|
||
sys.stdout.flush()
|
||
rv = EasyDialogs.AskString("")
|
||
if rv is None:
|
||
return ""
|
||
return rv + '\n'
|
||
|
||
|
||
def installconsole(defaultshow = 1):
|
||
global console
|
||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
||
if not prefs.console or not hasattr(prefs.console, 'show'):
|
||
prefs.console.show = defaultshow
|
||
if not hasattr(prefs.console, "windowbounds"):
|
||
prefs.console.windowbounds = (450, 250)
|
||
if not hasattr(prefs.console, "fontsettings"):
|
||
prefs.console.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
|
||
if not hasattr(prefs.console, "tabsettings"):
|
||
prefs.console.tabsettings = (32, 0)
|
||
console = PyConsole(prefs.console.windowbounds, prefs.console.show,
|
||
prefs.console.fontsettings, prefs.console.tabsettings, 1)
|
||
|
||
def installoutput(defaultshow = 0, OutPutWindow = PyOutput):
|
||
global output
|
||
|
||
# quick 'n' dirty std in emulation
|
||
sys.stdin = SimpleStdin()
|
||
|
||
prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
|
||
if not prefs.output or not hasattr(prefs.output, 'show'):
|
||
prefs.output.show = defaultshow
|
||
if not hasattr(prefs.output, "windowbounds"):
|
||
prefs.output.windowbounds = (450, 250)
|
||
if not hasattr(prefs.output, "fontsettings"):
|
||
prefs.output.fontsettings = ("Monaco", 0, 9, (0, 0, 0))
|
||
if not hasattr(prefs.output, "tabsettings"):
|
||
prefs.output.tabsettings = (32, 0)
|
||
output = OutPutWindow(prefs.output.windowbounds, prefs.output.show,
|
||
prefs.output.fontsettings, prefs.output.tabsettings)
|