summaryrefslogtreecommitdiffstats
path: root/Tools/idle/OutputWindow.py
blob: f03aaee15ff5c4e406cc7e35447570d88353f3ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from Tkinter import *
from EditorWindow import EditorWindow
import re
import tkMessageBox

class OutputWindow(EditorWindow):

    """An editor window that can serve as an output file.

    Also the future base class for the Python shell window.
    This class has no input facilities.
    """

    def __init__(self, *args):
        apply(EditorWindow.__init__, (self,) + args)
        self.text.bind("<<goto-file-line>>", self.goto_file_line)

    # Customize EditorWindow

    def ispythonsource(self, filename):
        # No colorization needed
        return 0

    def short_title(self):
        return "Output"

    def maybesave(self):
        # Override base class method -- don't ask any questions
        if self.get_saved():
            return "yes"
        else:
            return "no"

    # Act as output file

    def write(self, s, tags=(), mark="insert"):
        self.text.insert(mark, str(s), tags)
        self.text.see(mark)
        self.text.update()

    def writelines(self, l):
        map(self.write, l)

    def flush(self):
        pass

    # Our own right-button menu

    rmenu_specs = [
        ("Go to file/line", "<<goto-file-line>>"),
    ]

    file_line_pats = [
        r'file "([^"]*)", line (\d+)',
        r'([^\s]+)\((\d+)\)',
        r'([^\s]+):\s*(\d+):',
    ]

    file_line_progs = None

    def goto_file_line(self, event=None):
        if self.file_line_progs is None:
            l = []
            for pat in self.file_line_pats:
                l.append(re.compile(pat, re.IGNORECASE))
            self.file_line_progs = l
        # x, y = self.event.x, self.event.y
        # self.text.mark_set("insert", "@%d,%d" % (x, y))
        line = self.text.get("insert linestart", "insert lineend")
        for prog in self.file_line_progs:
            m = prog.search(line)
            if m:
                break
        else:
            tkMessageBox.showerror("No special line",
                "The line you point at doesn't look like "
                "a file name followed by a line number.",
                master=self.text)
            return
        filename, lineno = m.group(1, 2)
        try:
            f = open(filename, "r")
            f.close()
        except IOError, msg:
            self.text.bell()
            return
        edit = self.flist.open(filename)
        try:
            lineno = int(lineno)
        except ValueError, msg:
            self.text.bell()
            return
        edit.gotoline(lineno)

# These classes are currently not used but might come in handy

class OnDemandOutputWindow:

    tagdefs = {
        # XXX Should use IdlePrefs.ColorPrefs
        "stdout":  {"foreground": "blue"},
        "stderr":  {"foreground": "#007700"},
    }   
    
    def __init__(self, flist):
        self.flist = flist
        self.owin = None
    
    def write(self, s, tags, mark):
        if not self.owin:
            self.setup()
        self.owin.write(s, tags, mark)
    
    def setup(self):
        self.owin = owin = OutputWindow(self.flist)
        text = owin.text
        for tag, cnf in self.tagdefs.items():
            if cnf:
                apply(text.tag_configure, (tag,), cnf)
        text.tag_raise('sel')
        self.write = self.owin.write

class PseudoFile:

    def __init__(self, owin, tags, mark="end"):
        self.owin = owin
        self.tags = tags
        self.mark = mark

    def write(self, s):
        self.owin.write(s, self.tags, self.mark)

    def writelines(self, l):
        map(self.write, l)

    def flush(self):
        pass