summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/idlelib/IOBinding.py90
-rw-r--r--Lib/idlelib/config-main.def1
-rw-r--r--Lib/idlelib/configDialog.py23
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: