blob: 2028ed14689bfdcd504afb8d56f62ed8681f8a34 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001import sys
2import os
3import string
4from Tkinter import *
5
6
7class EditorWindow:
8
9 from Percolator import Percolator
10 from ColorDelegator import ColorDelegator
11 from UndoDelegator import UndoDelegator
12 from IOBinding import IOBinding
13 from SearchBinding import SearchBinding
14 from AutoIndent import AutoIndent
15 from AutoExpand import AutoExpand
16 import Bindings
17
18 def __init__(self, root, filename=None):
19 self.top = top = Toplevel(root)
20 self.vbar = vbar = Scrollbar(top, name='vbar')
21 self.text = text = Text(top, name='text')
22
23 self.Bindings.apply_bindings(text)
24
25 self.top.protocol("WM_DELETE_WINDOW", self.close)
26 self.top.bind("<<close-window>>", self.close_event)
27 self.text.bind("<<center-insert>>", self.center_insert_event)
28
29 vbar['command'] = text.yview
30 vbar.pack(side=RIGHT, fill=Y)
31
32 text['yscrollcommand'] = vbar.set
33 text['background'] = 'white'
34 if sys.platform[:3] == 'win':
35 text['font'] = ("lucida console", 8)
36 text.pack(side=LEFT, fill=BOTH, expand=1)
37 text.focus_set()
38
39 self.auto = auto = self.AutoIndent(text)
40 self.autoex = self.AutoExpand(text)
41 self.per = per = self.Percolator(text)
42 if self.ispythonsource(filename):
43 self.color = color = self.ColorDelegator(); per.insertfilter(color)
44 ##print "Initial colorizer"
45 else:
46 ##print "No initial colorizer"
47 self.color = None
48 self.undo = undo = self.UndoDelegator(); per.insertfilter(undo)
49 self.search = search = self.SearchBinding(undo)
50 self.io = io = self.IOBinding(undo)
51
52 undo.set_saved_change_hook(self.saved_change_hook)
53 io.set_filename_change_hook(self.filename_change_hook)
54
55 if filename:
56 if os.path.exists(filename):
57 io.loadfile(filename)
58 else:
59 io.set_filename(filename)
60
61 self.saved_change_hook()
62
63 def gotoline(self, lineno):
64 if lineno is not None and lineno > 0:
65 self.text.mark_set("insert", "%d.0" % lineno)
66 self.text.tag_remove("sel", "1.0", "end")
67 self.text.tag_add("sel", "insert", "insert +1l")
68 self.center()
69
70 def ispythonsource(self, filename):
71 if not filename:
72 return 1
73 if os.path.normcase(filename[-3:]) == ".py":
74 return 1
75 try:
76 f = open(filename)
77 line = f.readline()
78 f.close()
79 except IOError:
80 return 0
81 return line[:2] == '#!' and string.find(line, 'python') >= 0
82
83 close_hook = None
84
85 def set_close_hook(self, close_hook):
86 self.close_hook = close_hook
87
88 def filename_change_hook(self):
89 self.saved_change_hook()
90 if self.ispythonsource(self.io.filename):
91 self.addcolorizer()
92 else:
93 self.rmcolorizer()
94
95 def addcolorizer(self):
96 if self.color:
97 return
98 ##print "Add colorizer"
99 self.per.removefilter(self.undo)
100 self.color = self.ColorDelegator()
101 self.per.insertfilter(self.color)
102 self.per.insertfilter(self.undo)
103
104 def rmcolorizer(self):
105 if not self.color:
106 return
107 ##print "Remove colorizer"
108 self.per.removefilter(self.undo)
109 self.per.removefilter(self.color)
110 self.color = None
111 self.per.insertfilter(self.undo)
112
113 def saved_change_hook(self):
114 if self.io.filename:
115 title = self.io.filename
116 else:
117 title = "(Untitled)"
118 if not self.undo.get_saved():
119 title = title + " *"
120 self.top.wm_title(title)
121
122 def center_insert_event(self, event):
123 self.center()
124
125 def center(self, mark="insert"):
126 insert = float(self.text.index(mark + " linestart"))
127 end = float(self.text.index("end"))
128 if insert > end-insert:
129 self.text.see("1.0")
130 else:
131 self.text.see("end")
132 self.text.see(mark)
133
134 def close_event(self, event):
135 self.close()
136
137 def close(self):
138 self.top.wm_deiconify()
139 self.top.tkraise()
140 reply = self.io.maybesave()
141 if reply != "cancel":
142 if self.color and self.color.colorizing:
143 self.color.close()
144 self.top.bell()
145 return "cancel"
146 if self.close_hook:
147 self.close_hook()
148 if self.color:
149 self.color.close() # Cancel colorization
150 self.top.destroy()
151 return reply
152
153
154def fixwordbreaks(root):
155 tk = root.tk
156 tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
157 tk.call('set', 'tcl_wordchars', '[a-zA-Z0-9_]')
158 tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
159
160
161def test():
162 root = Tk()
163 fixwordbreaks(root)
164 root.withdraw()
165 if sys.argv[1:]:
166 filename = sys.argv[1]
167 else:
168 filename = None
169 edit = EditorWindow(root, filename)
170 edit.set_close_hook(root.quit)
171 root.mainloop()
172 root.destroy()
173
174if __name__ == '__main__':
175 test()