Updated for 2.1b2 distribution.
[python/dscho.git] / Tools / idle / OutputWindow.py
blob3d97362a21ffbee41b24d3d370105e00b4de3835
1 from Tkinter import *
2 from EditorWindow import EditorWindow
3 import re
4 import tkMessageBox
6 class OutputWindow(EditorWindow):
8 """An editor window that can serve as an output file.
10 Also the future base class for the Python shell window.
11 This class has no input facilities.
12 """
14 def __init__(self, *args):
15 apply(EditorWindow.__init__, (self,) + args)
16 self.text.bind("<<goto-file-line>>", self.goto_file_line)
18 # Customize EditorWindow
20 def ispythonsource(self, filename):
21 # No colorization needed
22 return 0
24 def short_title(self):
25 return "Output"
27 def maybesave(self):
28 # Override base class method -- don't ask any questions
29 if self.get_saved():
30 return "yes"
31 else:
32 return "no"
34 # Act as output file
36 def write(self, s, tags=(), mark="insert"):
37 self.text.insert(mark, str(s), tags)
38 self.text.see(mark)
39 self.text.update()
41 def writelines(self, l):
42 map(self.write, l)
44 def flush(self):
45 pass
47 # Our own right-button menu
49 rmenu_specs = [
50 ("Go to file/line", "<<goto-file-line>>"),
53 file_line_pats = [
54 r'file "([^"]*)", line (\d+)',
55 r'([^\s]+)\((\d+)\)',
56 r'([^\s]+):\s*(\d+):',
59 file_line_progs = None
61 def goto_file_line(self, event=None):
62 if self.file_line_progs is None:
63 l = []
64 for pat in self.file_line_pats:
65 l.append(re.compile(pat, re.IGNORECASE))
66 self.file_line_progs = l
67 # x, y = self.event.x, self.event.y
68 # self.text.mark_set("insert", "@%d,%d" % (x, y))
69 line = self.text.get("insert linestart", "insert lineend")
70 result = self._file_line_helper(line)
71 if not result:
72 # Try the previous line. This is handy e.g. in tracebacks,
73 # where you tend to right-click on the displayed source line
74 line = self.text.get("insert -1line linestart",
75 "insert -1line lineend")
76 result = self._file_line_helper(line)
77 if not result:
78 tkMessageBox.showerror(
79 "No special line",
80 "The line you point at doesn't look like "
81 "a valid file name followed by a line number.",
82 master=self.text)
83 return
84 filename, lineno = result
85 edit = self.flist.open(filename)
86 edit.gotoline(lineno)
88 def _file_line_helper(self, line):
89 for prog in self.file_line_progs:
90 m = prog.search(line)
91 if m:
92 break
93 else:
94 return None
95 filename, lineno = m.group(1, 2)
96 try:
97 f = open(filename, "r")
98 f.close()
99 except IOError:
100 return None
101 try:
102 return filename, int(lineno)
103 except TypeError:
104 return None
106 # These classes are currently not used but might come in handy
108 class OnDemandOutputWindow:
110 tagdefs = {
111 # XXX Should use IdlePrefs.ColorPrefs
112 "stdout": {"foreground": "blue"},
113 "stderr": {"foreground": "#007700"},
116 def __init__(self, flist):
117 self.flist = flist
118 self.owin = None
120 def write(self, s, tags, mark):
121 if not self.owin:
122 self.setup()
123 self.owin.write(s, tags, mark)
125 def setup(self):
126 self.owin = owin = OutputWindow(self.flist)
127 text = owin.text
128 for tag, cnf in self.tagdefs.items():
129 if cnf:
130 apply(text.tag_configure, (tag,), cnf)
131 text.tag_raise('sel')
132 self.write = self.owin.write
134 class PseudoFile:
136 def __init__(self, owin, tags, mark="end"):
137 self.owin = owin
138 self.tags = tags
139 self.mark = mark
141 def write(self, s):
142 self.owin.write(s, self.tags, self.mark)
144 def writelines(self, l):
145 map(self.write, l)
147 def flush(self):
148 pass