blob: 0d61afce7952ae266fa055448b82cd8441e62904 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001import os
2import tkFileDialog
3import tkMessageBox
4
5
6class IOBinding:
7
8 # Calls to non-standard text methods:
9 # reset_undo()
10 # set_saved(1)
11
12 def __init__(self, text):
13 self.text = text
14 self.text.bind("<<open-window-from-file>>", self.open)
15 self.text.bind("<<save-window>>", self.save)
16 self.text.bind("<<save-window-as-file>>", self.save_as)
17 self.text.bind("<<save-copy-of-window-as-file>>", self.save_a_copy)
18
19 filename_change_hook = None
20
21 def set_filename_change_hook(self, hook):
22 self.filename_change_hook = hook
23
24 filename = None
25
26 def set_filename(self, filename):
27 self.filename = filename
28 self.text.set_saved(1)
29 if self.filename_change_hook:
30 self.filename_change_hook()
31
32 def open(self, event):
33 if not self.text.get_saved():
34 reply = self.maybesave()
35 if reply == "cancel":
36 return "break"
37 filename = self.askopenfile()
38 if filename:
39 self.loadfile(filename)
40 return "break"
41
42 def loadfile(self, filename):
43 try:
44 f = open(filename)
45 chars = f.read()
46 f.close()
47 except IOError, msg:
48 tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
49 return 0
50 self.text.delete("1.0", "end")
51 self.set_filename(None)
52 self.text.insert("1.0", chars)
53 self.text.reset_undo()
54 self.set_filename(filename)
55 self.text.mark_set("insert", "1.0")
56 self.text.see("insert")
57 return 1
58
59 def maybesave(self):
60 if self.text.get_saved():
61 return "yes"
62 message = "Do you want to save %s before closing?" % (
63 self.filename or "this untitled document")
64 m = tkMessageBox.Message(
65 title="Save On Close",
66 message=message,
67 icon=tkMessageBox.QUESTION,
68 type=tkMessageBox.YESNOCANCEL,
69 master=self.text)
70 reply = m.show()
71 if reply == "yes":
72 self.save(None)
73 if not self.text.get_saved():
74 reply = "cancel"
75 return reply
76
77 def save(self, event):
78 if not self.filename:
79 self.save_as(event)
80 else:
81 if self.writefile(self.filename):
82 self.text.set_saved(1)
83 return "break"
84
85 def save_as(self, event):
86 filename = self.asksavefile()
87 if filename:
88 if self.writefile(filename):
89 self.set_filename(filename)
90 self.text.set_saved(1)
91 return "break"
92
93 def save_a_copy(self, event):
94 filename = self.asksavefile()
95 if filename:
96 self.writefile(filename)
97 return "break"
98
99 def writefile(self, filename):
100 try:
101 f = open(filename, "w")
102 chars = self.text.get("1.0", "end-1c")
103 f.write(chars)
104 if chars and chars[-1] != "\n":
105 f.write("\n")
106 f.close()
107 ## print "saved to", `filename`
108 return 1
109 except IOError, msg:
110 tkMessageBox.showerror("I/O Error", str(msg),
111 master=self.text)
112 return 0
113
114 opendialog = None
115 savedialog = None
116
117 filetypes = [
118 ("Python files", "*.py", "TEXT"),
119 ("All text files", "*", "TEXT"),
120 ("All files", "*"),
121 ]
122
123 def askopenfile(self):
124 dir, base = self.defaultfilename("open")
125 if not self.opendialog:
126 self.opendialog = tkFileDialog.Open(master=self.text,
127 filetypes=self.filetypes)
128 return self.opendialog.show(initialdir=dir, initialfile=base)
129
130 def defaultfilename(self, mode="open"):
131 if self.filename:
132 dir, base = os.path.split(self.filename)
133 else:
134 dir = base = ""
135 return dir, base
136
137 def asksavefile(self):
138 dir, base = self.defaultfilename("save")
139 if not self.savedialog:
140 self.savedialog = tkFileDialog.SaveAs(master=self.text,
141 filetypes=self.filetypes)
142 return self.savedialog.show(initialdir=dir, initialfile=base)
143
144
145def test():
146 from Tkinter import *
147 root = Tk()
148 class MyText(Text):
149 def reset_undo(self): pass
150 def set_saved(self, flag): pass
151 text = MyText(root)
152 text.pack()
153 text.focus_set()
154 io = IOBinding(text)
155 root.mainloop()
156
157if __name__ == "__main__":
158 test()