blob: 6a41a37500cb5cfa2e2d73c2c1965a62f7a7ab94 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001import os
2import tkFileDialog
3import tkMessageBox
4
Guido van Rossum504b0bf1999-01-02 21:28:54 +00005#$ event <<open-window-from-file>>
6#$ win <Control-o>
7#$ unix <Control-x><Control-f>
8
9#$ event <<save-window>>
10#$ win <Control-s>
11#$ unix <Control-x><Control-s>
12
13#$ event <<save-window-as-file>>
14#$ win <Alt-s>
15#$ unix <Control-x><Control-w>
16
17#$ event <<save-copy-of-window-as-file>>
18#$ win <Alt-Shift-s>
19#$ unix <Control-x><w>
20
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000021
22class IOBinding:
23
Guido van Rossum504b0bf1999-01-02 21:28:54 +000024 def __init__(self, editwin):
25 self.editwin = editwin
26 self.text = editwin.text
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000027 self.text.bind("<<open-window-from-file>>", self.open)
28 self.text.bind("<<save-window>>", self.save)
29 self.text.bind("<<save-window-as-file>>", self.save_as)
30 self.text.bind("<<save-copy-of-window-as-file>>", self.save_a_copy)
31
Guido van Rossum504b0bf1999-01-02 21:28:54 +000032 def get_saved(self):
33 return self.editwin.get_saved()
34
35 def set_saved(self, flag):
36 self.editwin.set_saved(flag)
37
38 def reset_undo(self):
39 self.editwin.reset_undo()
40
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000041 filename_change_hook = None
42
43 def set_filename_change_hook(self, hook):
44 self.filename_change_hook = hook
45
46 filename = None
47
48 def set_filename(self, filename):
49 self.filename = filename
Guido van Rossum504b0bf1999-01-02 21:28:54 +000050 self.set_saved(1)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000051 if self.filename_change_hook:
52 self.filename_change_hook()
53
54 def open(self, event):
Guido van Rossum504b0bf1999-01-02 21:28:54 +000055 if self.editwin.flist:
56 filename = self.askopenfile()
57 if filename:
58 self.editwin.flist.open(filename)
59 else:
60 self.text.focus_set()
61 return "break"
62 # Code for use outside IDLE:
63 if self.get_saved():
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000064 reply = self.maybesave()
65 if reply == "cancel":
Guido van Rossum504b0bf1999-01-02 21:28:54 +000066 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000067 return "break"
68 filename = self.askopenfile()
69 if filename:
70 self.loadfile(filename)
Guido van Rossum504b0bf1999-01-02 21:28:54 +000071 else:
72 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000073 return "break"
74
75 def loadfile(self, filename):
76 try:
77 f = open(filename)
78 chars = f.read()
79 f.close()
80 except IOError, msg:
81 tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
82 return 0
83 self.text.delete("1.0", "end")
84 self.set_filename(None)
85 self.text.insert("1.0", chars)
Guido van Rossum504b0bf1999-01-02 21:28:54 +000086 self.reset_undo()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000087 self.set_filename(filename)
88 self.text.mark_set("insert", "1.0")
89 self.text.see("insert")
90 return 1
91
92 def maybesave(self):
Guido van Rossum504b0bf1999-01-02 21:28:54 +000093 if self.get_saved():
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000094 return "yes"
95 message = "Do you want to save %s before closing?" % (
96 self.filename or "this untitled document")
97 m = tkMessageBox.Message(
98 title="Save On Close",
99 message=message,
100 icon=tkMessageBox.QUESTION,
101 type=tkMessageBox.YESNOCANCEL,
102 master=self.text)
103 reply = m.show()
104 if reply == "yes":
105 self.save(None)
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000106 if not self.get_saved():
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000107 reply = "cancel"
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000108 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000109 return reply
110
111 def save(self, event):
112 if not self.filename:
113 self.save_as(event)
114 else:
115 if self.writefile(self.filename):
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000116 self.set_saved(1)
117 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000118 return "break"
119
120 def save_as(self, event):
121 filename = self.asksavefile()
122 if filename:
123 if self.writefile(filename):
124 self.set_filename(filename)
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000125 self.set_saved(1)
126 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000127 return "break"
128
129 def save_a_copy(self, event):
130 filename = self.asksavefile()
131 if filename:
132 self.writefile(filename)
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000133 self.text.focus_set()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000134 return "break"
135
136 def writefile(self, filename):
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000137 self.fixlastline()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000138 try:
139 f = open(filename, "w")
140 chars = self.text.get("1.0", "end-1c")
141 f.write(chars)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000142 f.close()
143 ## print "saved to", `filename`
144 return 1
145 except IOError, msg:
146 tkMessageBox.showerror("I/O Error", str(msg),
147 master=self.text)
148 return 0
149
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000150 def fixlastline(self):
151 c = self.text.get("end-2c")
152 if c != '\n':
153 self.text.insert("end-1c", "\n")
154
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000155 opendialog = None
156 savedialog = None
157
158 filetypes = [
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000159 ("Python and text files", "*.py *.pyw *.txt", "TEXT"),
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000160 ("All text files", "*", "TEXT"),
161 ("All files", "*"),
162 ]
163
164 def askopenfile(self):
165 dir, base = self.defaultfilename("open")
166 if not self.opendialog:
167 self.opendialog = tkFileDialog.Open(master=self.text,
168 filetypes=self.filetypes)
169 return self.opendialog.show(initialdir=dir, initialfile=base)
170
171 def defaultfilename(self, mode="open"):
172 if self.filename:
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000173 return os.path.split(self.filename)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000174 else:
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000175 try:
176 pwd = os.getcwd()
177 except os.error:
178 pwd = ""
179 return pwd, ""
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000180
181 def asksavefile(self):
182 dir, base = self.defaultfilename("save")
183 if not self.savedialog:
184 self.savedialog = tkFileDialog.SaveAs(master=self.text,
185 filetypes=self.filetypes)
186 return self.savedialog.show(initialdir=dir, initialfile=base)
187
188
189def test():
190 from Tkinter import *
191 root = Tk()
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000192 class MyEditWin:
193 def __init__(self, text):
194 self.text = text
195 self.flist = None
196 self.text.bind("<Control-o>", self.open)
197 self.text.bind("<Control-s>", self.save)
198 self.text.bind("<Alt-s>", self.save_as)
199 self.text.bind("<Alt-z>", self.save_a_copy)
200 def get_saved(self): return 0
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000201 def set_saved(self, flag): pass
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000202 def reset_undo(self): pass
203 def open(self, event):
204 self.text.event_generate("<<open-window-from-file>>")
205 def save(self, event):
206 self.text.event_generate("<<save-window>>")
207 def save_as(self, event):
208 self.text.event_generate("<<save-window-as-file>>")
209 def save_a_copy(self, event):
210 self.text.event_generate("<<save-copy-of-window-as-file>>")
211 text = Text(root)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000212 text.pack()
213 text.focus_set()
Guido van Rossum504b0bf1999-01-02 21:28:54 +0000214 editwin = MyEditWin(text)
215 io = IOBinding(editwin)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000216 root.mainloop()
217
218if __name__ == "__main__":
219 test()