diff options
-rw-r--r-- | Lib/idlelib/IOBinding.py | 90 | ||||
-rw-r--r-- | Lib/idlelib/config-main.def | 1 | ||||
-rw-r--r-- | Lib/idlelib/configDialog.py | 23 |
3 files changed, 101 insertions, 13 deletions
diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py index 6f46a60..5d7a221 100644 --- a/Lib/idlelib/IOBinding.py +++ b/Lib/idlelib/IOBinding.py @@ -13,6 +13,8 @@ import tempfile import tkFileDialog import tkMessageBox import re +from Tkinter import * +from SimpleDialog import SimpleDialog from configHandler import idleConf @@ -67,6 +69,52 @@ encoding = encoding.lower() coding_re = re.compile("coding[:=]\s*([-\w_.]+)") +class EncodingMessage(SimpleDialog): + "Inform user that an encoding declaration is needed." + def __init__(self, master, enc): + self.should_edit = False + + self.root = top = Toplevel(master) + top.bind("<Return>", self.return_event) + top.bind("<Escape>", self.do_ok) + top.protocol("WM_DELETE_WINDOW", self.wm_delete_window) + top.wm_title("I/O Warning") + top.wm_iconname("I/O Warning") + self.top = top + + l1 = Label(top, + text="Non-ASCII found, yet no encoding declared. Add a line like") + l1.pack(side=TOP, anchor=W) + l2 = Entry(top, font="courier") + l2.insert(0, "# -*- coding: %s -*-" % enc) + # For some reason, the text is not selectable anymore if the + # widget is disabled. + # l2['state'] = DISABLED + l2.pack(side=TOP, anchor = W, fill=X) + l3 = Label(top, text="to your file\n" + "Choose OK to save this file as %s\n" + "Edit your general options to silence this warning" % enc) + l3.pack(side=TOP, anchor = W) + + buttons = Frame(top) + buttons.pack(side=TOP, fill=X) + # Both return and cancel mean the same thing: do nothing + self.default = self.cancel = 0 + b1 = Button(buttons, text="Ok", default="active", + command=self.do_ok) + b1.pack(side=LEFT, fill=BOTH, expand=1) + b2 = Button(buttons, text="Edit my file", + command=self.do_edit) + b2.pack(side=LEFT, fill=BOTH, expand=1) + + self._set_transient(master) + + def do_ok(self): + self.done(0) + + def do_edit(self): + self.done(1) + def coding_spec(str): """Return the encoding declaration according to PEP 263. @@ -368,18 +416,35 @@ class IOBinding: return BOM_UTF8 + chars.encode("utf-8") # Nothing was declared, and we had not determined an encoding # on loading. Recommend an encoding line. - try: - chars = chars.encode(encoding) - enc = encoding - except UnicodeError: - chars = BOM_UTF8 + chars.encode("utf-8") - enc = "utf-8" - tkMessageBox.showerror( - "I/O Error", - "Non-ASCII found, yet no encoding declared. Add a line like\n" - "# -*- coding: %s -*- \nto your file" % enc, - master = self.text) - return chars + config_encoding = idleConf.GetOption("main","EditorWindow", + "encoding") + if config_encoding == 'utf-8': + # User has requested that we save files as UTF-8 + return BOM_UTF8 + chars.encode("utf-8") + ask_user = True + try: + chars = chars.encode(encoding) + enc = encoding + if config_encoding == 'locale': + ask_user = False + except UnicodeError: + chars = BOM_UTF8 + chars.encode("utf-8") + enc = "utf-8" + if not ask_user: + return chars + dialog = EncodingMessage(self.editwin.top, enc) + dialog.go() + if dialog.num == 1: + # User asked us to edit the file + encline = "# -*- coding: %s -*-\n" % enc + firstline = self.text.get("1.0", "2.0") + if firstline.startswith("#!"): + # Insert encoding after #! line + self.text.insert("2.0", encline) + else: + self.text.insert("1.0", encline) + return self.encode(self.text.get("1.0", "end-1c")) + return chars def fixlastline(self): c = self.text.get("end-2c") @@ -487,5 +552,4 @@ def test(): root.mainloop() if __name__ == "__main__": - from Tkinter import * test() diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index 9d520c1..a6388d1 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -49,6 +49,7 @@ height= 30 font= courier font-size= 12 font-bold= 0 +encoding=none [Indent] use-spaces= 1 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index 814689c..6cbc74f 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -334,6 +334,7 @@ class ConfigDialog(Toplevel): self.winWidth=StringVar(self) self.winHeight=StringVar(self) self.startupEdit=IntVar(self) + self.encoding=StringVar(self) self.userHelpBrowser=BooleanVar(self) self.helpBrowser=StringVar(self) #widget creation @@ -342,6 +343,7 @@ class ConfigDialog(Toplevel): #body section frames frameRun=Frame(frame,borderwidth=2,relief=GROOVE) frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) + frameEncoding=Frame(frame,borderwidth=2,relief=GROOVE) frameHelp=Frame(frame,borderwidth=2,relief=GROOVE) #frameRun labelRunTitle=Label(frameRun,text='Startup Preferences') @@ -359,6 +361,14 @@ class ConfigDialog(Toplevel): labelWinHeightTitle=Label(frameWinSize,text='Height') entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, width=3) + #frameEncoding + labelEncodingTitle=Label(frameEncoding,text="Default Source Encoding") + radioEncLocale=Radiobutton(frameEncoding,variable=self.encoding, + value="locale",text="Locale-defined") + radioEncUTF8=Radiobutton(frameEncoding,variable=self.encoding, + value="utf-8",text="UTF-8") + radioEncNone=Radiobutton(frameEncoding,variable=self.encoding, + value="none",text="None") #frameHelp labelHelpTitle=Label(frameHelp,text='Help Options') frameHelpList=Frame(frameHelp) @@ -387,6 +397,7 @@ class ConfigDialog(Toplevel): #body frameRun.pack(side=TOP,padx=5,pady=5,fill=X) frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) + frameEncoding.pack(side=TOP,padx=5,pady=5,fill=X) frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) #frameRun labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5) @@ -399,6 +410,11 @@ class ConfigDialog(Toplevel): labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) + #frameEncoding + labelEncodingTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + radioEncNone.pack(side=RIGHT,anchor=E,pady=5) + radioEncUTF8.pack(side=RIGHT,anchor=E,pady=5) + radioEncLocale.pack(side=RIGHT,anchor=E,pady=5) #frameHelp labelHelpTitle.pack(side=TOP,anchor=W,padx=5,pady=5) frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) @@ -432,6 +448,7 @@ class ConfigDialog(Toplevel): self.winWidth.trace_variable('w',self.VarChanged_winWidth) self.winHeight.trace_variable('w',self.VarChanged_winHeight) self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) + self.encoding.trace_variable('w',self.VarChanged_encoding) def VarChanged_fontSize(self,*params): value=self.fontSize.get() @@ -525,6 +542,10 @@ class ConfigDialog(Toplevel): value=self.startupEdit.get() self.AddChangedItem('main','General','editor-on-startup',value) + def VarChanged_encoding(self,*params): + value=self.encoding.get() + self.AddChangedItem('main','EditorWindow','encoding',value) + def ResetChangedItems(self): #When any config item is changed in this dialog, an entry #should be made in the relevant section (config type) of this @@ -1020,6 +1041,8 @@ class ConfigDialog(Toplevel): #initial window size self.winWidth.set(idleConf.GetOption('main','EditorWindow','width')) self.winHeight.set(idleConf.GetOption('main','EditorWindow','height')) + # default source encoding + self.encoding.set(idleConf.GetOption('main','EditorWindow','encoding')) # additional help sources self.userHelpList = idleConf.GetAllExtraHelpSourcesList() for helpItem in self.userHelpList: |