blob: e18d846d8def36464478c9059cfc5586b3986ef2 [file] [log] [blame]
Georg Brandl6634bf22008-05-20 07:13:37 +00001from Tkinter import *
Florent Xiclunad630c042010-04-02 07:24:52 +00002from idlelib.EditorWindow import EditorWindow
David Scherer7aced172000-08-15 01:13:23 +00003import re
Georg Brandl6634bf22008-05-20 07:13:37 +00004import tkMessageBox
Florent Xiclunad630c042010-04-02 07:24:52 +00005from idlelib import IOBinding
David Scherer7aced172000-08-15 01:13:23 +00006
David Scherer7aced172000-08-15 01:13:23 +00007class OutputWindow(EditorWindow):
Kurt B. Kaiser969de452002-06-12 03:28:57 +00008
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.
David Scherer7aced172000-08-15 01:13:23 +000013 """
14
Kurt B. Kaiser969de452002-06-12 03:28:57 +000015 def __init__(self, *args):
Raymond Hettinger931237e2003-07-09 18:48:24 +000016 EditorWindow.__init__(self, *args)
David Scherer7aced172000-08-15 01:13:23 +000017 self.text.bind("<<goto-file-line>>", self.goto_file_line)
David Scherer7aced172000-08-15 01:13:23 +000018
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
David Scherer7aced172000-08-15 01:13:23 +000028 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
David Scherer7aced172000-08-15 01:13:23 +000035 # Act as output file
36
Kurt B. Kaiser969de452002-06-12 03:28:57 +000037 def write(self, s, tags=(), mark="insert"):
Kurt B. Kaiser7de37722003-06-15 17:49:59 +000038 # 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
Kurt B. Kaiserd0116362002-09-02 21:29:40 +000046 self.text.insert(mark, s, tags)
David Scherer7aced172000-08-15 01:13:23 +000047 self.text.see(mark)
48 self.text.update()
49
Florent Xiclunad630c042010-04-02 07:24:52 +000050 def writelines(self, lines):
51 for line in lines:
52 self.write(line)
David Scherer7aced172000-08-15 01:13:23 +000053
54 def flush(self):
55 pass
56
57 # Our own right-button menu
58
59 rmenu_specs = [
Andrew Svetlov5018db72012-11-01 22:39:14 +020060 ("Cut", "<<cut>>", "rmenu_check_cut"),
61 ("Copy", "<<copy>>", "rmenu_check_copy"),
62 ("Paste", "<<paste>>", "rmenu_check_paste"),
63 (None, None, None),
64 ("Go to file/line", "<<goto-file-line>>", None),
David Scherer7aced172000-08-15 01:13:23 +000065 ]
66
67 file_line_pats = [
Kurt B. Kaiser62e9a652009-05-03 02:05:22 +000068 # order of patterns matters
David Scherer7aced172000-08-15 01:13:23 +000069 r'file "([^"]*)", line (\d+)',
70 r'([^\s]+)\((\d+)\)',
Kurt B. Kaiser62e9a652009-05-03 02:05:22 +000071 r'^(\s*\S.*?):\s*(\d+):', # Win filename, maybe starting with spaces
72 r'([^\s]+):\s*(\d+):', # filename or path, ltrim
73 r'^\s*(\S.*?):\s*(\d+):', # Win abs path with embedded spaces, ltrim
David Scherer7aced172000-08-15 01:13:23 +000074 ]
75
76 file_line_progs = None
77
78 def goto_file_line(self, event=None):
79 if self.file_line_progs is None:
80 l = []
81 for pat in self.file_line_pats:
82 l.append(re.compile(pat, re.IGNORECASE))
83 self.file_line_progs = l
84 # x, y = self.event.x, self.event.y
85 # self.text.mark_set("insert", "@%d,%d" % (x, y))
86 line = self.text.get("insert linestart", "insert lineend")
87 result = self._file_line_helper(line)
88 if not result:
89 # Try the previous line. This is handy e.g. in tracebacks,
90 # where you tend to right-click on the displayed source line
91 line = self.text.get("insert -1line linestart",
92 "insert -1line lineend")
93 result = self._file_line_helper(line)
94 if not result:
95 tkMessageBox.showerror(
96 "No special line",
97 "The line you point at doesn't look like "
98 "a valid file name followed by a line number.",
99 master=self.text)
100 return
101 filename, lineno = result
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000102 edit = self.flist.open(filename)
David Scherer7aced172000-08-15 01:13:23 +0000103 edit.gotoline(lineno)
David Scherer7aced172000-08-15 01:13:23 +0000104
105 def _file_line_helper(self, line):
106 for prog in self.file_line_progs:
Kurt B. Kaiser94290d32009-04-26 23:22:11 +0000107 match = prog.search(line)
108 if match:
109 filename, lineno = match.group(1, 2)
110 try:
111 f = open(filename, "r")
112 f.close()
113 break
114 except IOError:
115 continue
David Scherer7aced172000-08-15 01:13:23 +0000116 else:
117 return None
David Scherer7aced172000-08-15 01:13:23 +0000118 try:
119 return filename, int(lineno)
120 except TypeError:
121 return None
122
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000123# These classes are currently not used but might come in handy
David Scherer7aced172000-08-15 01:13:23 +0000124
125class OnDemandOutputWindow:
David Scherer7aced172000-08-15 01:13:23 +0000126
127 tagdefs = {
128 # XXX Should use IdlePrefs.ColorPrefs
David Scherer7aced172000-08-15 01:13:23 +0000129 "stdout": {"foreground": "blue"},
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000130 "stderr": {"foreground": "#007700"},
131 }
132
David Scherer7aced172000-08-15 01:13:23 +0000133 def __init__(self, flist):
134 self.flist = flist
135 self.owin = None
David Scherer7aced172000-08-15 01:13:23 +0000136
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000137 def write(self, s, tags, mark):
138 if not self.owin:
David Scherer7aced172000-08-15 01:13:23 +0000139 self.setup()
140 self.owin.write(s, tags, mark)
141
David Scherer7aced172000-08-15 01:13:23 +0000142 def setup(self):
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000143 self.owin = owin = OutputWindow(self.flist)
David Scherer7aced172000-08-15 01:13:23 +0000144 text = owin.text
David Scherer7aced172000-08-15 01:13:23 +0000145 for tag, cnf in self.tagdefs.items():
146 if cnf:
Raymond Hettinger931237e2003-07-09 18:48:24 +0000147 text.tag_configure(tag, **cnf)
David Scherer7aced172000-08-15 01:13:23 +0000148 text.tag_raise('sel')
Kurt B. Kaiser969de452002-06-12 03:28:57 +0000149 self.write = self.owin.write