move sections
[python/dscho.git] / Lib / idlelib / OutputWindow.py
blob60d09c0cac0fe20e7ff3563af63150dc2330f38f
1 from Tkinter import *
2 from idlelib.EditorWindow import EditorWindow
3 import re
4 import tkMessageBox
5 from idlelib import IOBinding
7 class OutputWindow(EditorWindow):
9 """An editor window that can serve as an output file.
11 Also the future base class for the Python shell window.
12 This class has no input facilities.
13 """
15 def __init__(self, *args):
16 EditorWindow.__init__(self, *args)
17 self.text.bind("<<goto-file-line>>", self.goto_file_line)
19 # Customize EditorWindow
21 def ispythonsource(self, filename):
22 # No colorization needed
23 return 0
25 def short_title(self):
26 return "Output"
28 def maybesave(self):
29 # Override base class method -- don't ask any questions
30 if self.get_saved():
31 return "yes"
32 else:
33 return "no"
35 # Act as output file
37 def write(self, s, tags=(), mark="insert"):
38 # Tk assumes that byte strings are Latin-1;
39 # we assume that they are in the locale's encoding
40 if isinstance(s, str):
41 try:
42 s = unicode(s, IOBinding.encoding)
43 except UnicodeError:
44 # some other encoding; let Tcl deal with it
45 pass
46 self.text.insert(mark, s, tags)
47 self.text.see(mark)
48 self.text.update()
50 def writelines(self, lines):
51 for line in lines:
52 self.write(line)
54 def flush(self):
55 pass
57 # Our own right-button menu
59 rmenu_specs = [
60 ("Go to file/line", "<<goto-file-line>>"),
63 file_line_pats = [
64 # order of patterns matters
65 r'file "([^"]*)", line (\d+)',
66 r'([^\s]+)\((\d+)\)',
67 r'^(\s*\S.*?):\s*(\d+):', # Win filename, maybe starting with spaces
68 r'([^\s]+):\s*(\d+):', # filename or path, ltrim
69 r'^\s*(\S.*?):\s*(\d+):', # Win abs path with embedded spaces, ltrim
72 file_line_progs = None
74 def goto_file_line(self, event=None):
75 if self.file_line_progs is None:
76 l = []
77 for pat in self.file_line_pats:
78 l.append(re.compile(pat, re.IGNORECASE))
79 self.file_line_progs = l
80 # x, y = self.event.x, self.event.y
81 # self.text.mark_set("insert", "@%d,%d" % (x, y))
82 line = self.text.get("insert linestart", "insert lineend")
83 result = self._file_line_helper(line)
84 if not result:
85 # Try the previous line. This is handy e.g. in tracebacks,
86 # where you tend to right-click on the displayed source line
87 line = self.text.get("insert -1line linestart",
88 "insert -1line lineend")
89 result = self._file_line_helper(line)
90 if not result:
91 tkMessageBox.showerror(
92 "No special line",
93 "The line you point at doesn't look like "
94 "a valid file name followed by a line number.",
95 master=self.text)
96 return
97 filename, lineno = result
98 edit = self.flist.open(filename)
99 edit.gotoline(lineno)
101 def _file_line_helper(self, line):
102 for prog in self.file_line_progs:
103 match = prog.search(line)
104 if match:
105 filename, lineno = match.group(1, 2)
106 try:
107 f = open(filename, "r")
108 f.close()
109 break
110 except IOError:
111 continue
112 else:
113 return None
114 try:
115 return filename, int(lineno)
116 except TypeError:
117 return None
119 # These classes are currently not used but might come in handy
121 class OnDemandOutputWindow:
123 tagdefs = {
124 # XXX Should use IdlePrefs.ColorPrefs
125 "stdout": {"foreground": "blue"},
126 "stderr": {"foreground": "#007700"},
129 def __init__(self, flist):
130 self.flist = flist
131 self.owin = None
133 def write(self, s, tags, mark):
134 if not self.owin:
135 self.setup()
136 self.owin.write(s, tags, mark)
138 def setup(self):
139 self.owin = owin = OutputWindow(self.flist)
140 text = owin.text
141 for tag, cnf in self.tagdefs.items():
142 if cnf:
143 text.tag_configure(tag, **cnf)
144 text.tag_raise('sel')
145 self.write = self.owin.write