]> granicus.if.org Git - python/commitdiff
[ SF 710733 - Martin v. Loewis] Improving source encoding dialog
authorKurt B. Kaiser <kbk@shore.net>
Sat, 10 May 2003 00:49:56 +0000 (00:49 +0000)
committerKurt B. Kaiser <kbk@shore.net>
Sat, 10 May 2003 00:49:56 +0000 (00:49 +0000)
M IOBinding.py
M config-main.def
M configDialog.py

Lib/idlelib/IOBinding.py
Lib/idlelib/config-main.def
Lib/idlelib/configDialog.py

index 6f46a60d7846cf1d4661d6d134717a90e9fffc9b..5d7a221cfb291cc4a4df17b5e4932fa5615a2a92 100644 (file)
@@ -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()
index 9d520c106a1d9ffde5f77e5eae021748de0d1614..a6388d10323892160bec7370cf26700de50c1928 100644 (file)
@@ -49,6 +49,7 @@ height= 30
 font= courier
 font-size= 12
 font-bold= 0
+encoding=none
 
 [Indent]
 use-spaces= 1
index 814689c821253315eeb117f3fe4dc475cfb4db78..6cbc74f7865d7a28e4bdbab0dc1516b3b9101e00 100644 (file)
@@ -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: