Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | from Tkinter import * |
2 | from EditorWindow import EditorWindow | |
3 | import re | |
4 | import tkMessageBox | |
5 | import IOBinding | |
6 | ||
7 | class OutputWindow(EditorWindow): | |
8 | ||
9 | """An editor window that can serve as an output file. | |
10 | ||
11 | Also the future base class for the Python shell window. | |
12 | This class has no input facilities. | |
13 | """ | |
14 | ||
15 | def __init__(self, *args): | |
16 | EditorWindow.__init__(self, *args) | |
17 | self.text.bind("<<goto-file-line>>", self.goto_file_line) | |
18 | ||
19 | # Customize EditorWindow | |
20 | ||
21 | def ispythonsource(self, filename): | |
22 | # No colorization needed | |
23 | return 0 | |
24 | ||
25 | def short_title(self): | |
26 | return "Output" | |
27 | ||
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" | |
34 | ||
35 | # Act as output file | |
36 | ||
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() | |
49 | ||
50 | def writelines(self, l): | |
51 | map(self.write, l) | |
52 | ||
53 | def flush(self): | |
54 | pass | |
55 | ||
56 | # Our own right-button menu | |
57 | ||
58 | rmenu_specs = [ | |
59 | ("Go to file/line", "<<goto-file-line>>"), | |
60 | ] | |
61 | ||
62 | file_line_pats = [ | |
63 | r'file "([^"]*)", line (\d+)', | |
64 | r'([^\s]+)\((\d+)\)', | |
65 | r'([^\s]+):\s*(\d+):', | |
66 | ] | |
67 | ||
68 | file_line_progs = None | |
69 | ||
70 | def goto_file_line(self, event=None): | |
71 | if self.file_line_progs is None: | |
72 | l = [] | |
73 | for pat in self.file_line_pats: | |
74 | l.append(re.compile(pat, re.IGNORECASE)) | |
75 | self.file_line_progs = l | |
76 | # x, y = self.event.x, self.event.y | |
77 | # self.text.mark_set("insert", "@%d,%d" % (x, y)) | |
78 | line = self.text.get("insert linestart", "insert lineend") | |
79 | result = self._file_line_helper(line) | |
80 | if not result: | |
81 | # Try the previous line. This is handy e.g. in tracebacks, | |
82 | # where you tend to right-click on the displayed source line | |
83 | line = self.text.get("insert -1line linestart", | |
84 | "insert -1line lineend") | |
85 | result = self._file_line_helper(line) | |
86 | if not result: | |
87 | tkMessageBox.showerror( | |
88 | "No special line", | |
89 | "The line you point at doesn't look like " | |
90 | "a valid file name followed by a line number.", | |
91 | master=self.text) | |
92 | return | |
93 | filename, lineno = result | |
94 | edit = self.flist.open(filename) | |
95 | edit.gotoline(lineno) | |
96 | ||
97 | def _file_line_helper(self, line): | |
98 | for prog in self.file_line_progs: | |
99 | m = prog.search(line) | |
100 | if m: | |
101 | break | |
102 | else: | |
103 | return None | |
104 | filename, lineno = m.group(1, 2) | |
105 | try: | |
106 | f = open(filename, "r") | |
107 | f.close() | |
108 | except IOError: | |
109 | return None | |
110 | try: | |
111 | return filename, int(lineno) | |
112 | except TypeError: | |
113 | return None | |
114 | ||
115 | # These classes are currently not used but might come in handy | |
116 | ||
117 | class OnDemandOutputWindow: | |
118 | ||
119 | tagdefs = { | |
120 | # XXX Should use IdlePrefs.ColorPrefs | |
121 | "stdout": {"foreground": "blue"}, | |
122 | "stderr": {"foreground": "#007700"}, | |
123 | } | |
124 | ||
125 | def __init__(self, flist): | |
126 | self.flist = flist | |
127 | self.owin = None | |
128 | ||
129 | def write(self, s, tags, mark): | |
130 | if not self.owin: | |
131 | self.setup() | |
132 | self.owin.write(s, tags, mark) | |
133 | ||
134 | def setup(self): | |
135 | self.owin = owin = OutputWindow(self.flist) | |
136 | text = owin.text | |
137 | for tag, cnf in self.tagdefs.items(): | |
138 | if cnf: | |
139 | text.tag_configure(tag, **cnf) | |
140 | text.tag_raise('sel') | |
141 | self.write = self.owin.write | |
142 | ||
143 | #class PseudoFile: | |
144 | # | |
145 | # def __init__(self, owin, tags, mark="end"): | |
146 | # self.owin = owin | |
147 | # self.tags = tags | |
148 | # self.mark = mark | |
149 | ||
150 | # def write(self, s): | |
151 | # self.owin.write(s, self.tags, self.mark) | |
152 | ||
153 | # def writelines(self, l): | |
154 | # map(self.write, l) | |
155 | ||
156 | # def flush(self): | |
157 | # pass |