|
1 | 1 | """ |
2 | 2 | Dialog that allows user to specify a new config file section name. |
3 | 3 | Used to get new highlight theme and keybinding set names. |
| 4 | +The 'return value' for the dialog, used two placed in configDialog.py, |
| 5 | +is the .result attribute set in the Ok and Cancel methods. |
4 | 6 | """ |
5 | 7 | from tkinter import * |
6 | 8 | import tkinter.messagebox as tkMessageBox |
7 | 9 |
|
8 | 10 | class GetCfgSectionNameDialog(Toplevel): |
9 | | - def __init__(self,parent,title,message,usedNames): |
| 11 | + def __init__(self, parent, title, message, used_names): |
10 | 12 | """ |
11 | 13 | message - string, informational message to display |
12 | | - usedNames - list, list of names already in use for validity check |
| 14 | + used_names - string collection, names already in use for validity check |
13 | 15 | """ |
14 | 16 | Toplevel.__init__(self, parent) |
15 | 17 | self.configure(borderwidth=5) |
16 | | - self.resizable(height=FALSE,width=FALSE) |
| 18 | + self.resizable(height=FALSE, width=FALSE) |
17 | 19 | self.title(title) |
18 | 20 | self.transient(parent) |
19 | 21 | self.grab_set() |
20 | 22 | self.protocol("WM_DELETE_WINDOW", self.Cancel) |
21 | 23 | self.parent = parent |
22 | | - self.message=message |
23 | | - self.usedNames=usedNames |
24 | | - self.result='' |
25 | | - self.CreateWidgets() |
26 | | - self.withdraw() #hide while setting geometry |
| 24 | + self.message = message |
| 25 | + self.used_names = used_names |
| 26 | + self.create_widgets() |
| 27 | + self.withdraw() #hide while setting geometry |
27 | 28 | self.update_idletasks() |
28 | 29 | #needs to be done here so that the winfo_reqwidth is valid |
29 | 30 | self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) |
30 | | - self.geometry("+%d+%d" % |
31 | | - ((parent.winfo_rootx()+((parent.winfo_width()/2) |
32 | | - -(self.winfo_reqwidth()/2)), |
33 | | - parent.winfo_rooty()+((parent.winfo_height()/2) |
34 | | - -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent |
35 | | - self.deiconify() #geometry set, unhide |
| 31 | + self.geometry( |
| 32 | + "+%d+%d" % ( |
| 33 | + parent.winfo_rootx() + |
| 34 | + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), |
| 35 | + parent.winfo_rooty() + |
| 36 | + (parent.winfo_height()/2 - self.winfo_reqheight()/2) |
| 37 | + ) ) #centre dialog over parent |
| 38 | + self.deiconify() #geometry set, unhide |
36 | 39 | self.wait_window() |
37 | 40 |
|
38 | | - def CreateWidgets(self): |
39 | | - self.name=StringVar(self) |
40 | | - self.fontSize=StringVar(self) |
41 | | - self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN) |
42 | | - self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH) |
43 | | - self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5, |
44 | | - text=self.message)#,aspect=200) |
45 | | - entryName=Entry(self.frameMain,textvariable=self.name,width=30) |
| 41 | + def create_widgets(self): |
| 42 | + self.name = StringVar(self.parent) |
| 43 | + self.fontSize = StringVar(self.parent) |
| 44 | + self.frameMain = Frame(self, borderwidth=2, relief=SUNKEN) |
| 45 | + self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH) |
| 46 | + self.messageInfo = Message(self.frameMain, anchor=W, justify=LEFT, |
| 47 | + padx=5, pady=5, text=self.message) #,aspect=200) |
| 48 | + entryName = Entry(self.frameMain, textvariable=self.name, width=30) |
46 | 49 | entryName.focus_set() |
47 | | - self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH) |
48 | | - entryName.pack(padx=5,pady=5) |
49 | | - frameButtons=Frame(self) |
50 | | - frameButtons.pack(side=BOTTOM,fill=X) |
51 | | - self.buttonOk = Button(frameButtons,text='Ok', |
52 | | - width=8,command=self.Ok) |
53 | | - self.buttonOk.grid(row=0,column=0,padx=5,pady=5) |
54 | | - self.buttonCancel = Button(frameButtons,text='Cancel', |
55 | | - width=8,command=self.Cancel) |
56 | | - self.buttonCancel.grid(row=0,column=1,padx=5,pady=5) |
| 50 | + self.messageInfo.pack(padx=5, pady=5) #, expand=TRUE, fill=BOTH) |
| 51 | + entryName.pack(padx=5, pady=5) |
57 | 52 |
|
58 | | - def NameOk(self): |
59 | | - #simple validity check for a sensible |
60 | | - #ConfigParser file section name |
61 | | - nameOk=1 |
62 | | - name=self.name.get() |
63 | | - name.strip() |
| 53 | + frameButtons = Frame(self, pady=2) |
| 54 | + frameButtons.pack(side=BOTTOM) |
| 55 | + self.buttonOk = Button(frameButtons, text='Ok', |
| 56 | + width=8, command=self.Ok) |
| 57 | + self.buttonOk.pack(side=LEFT, padx=5) |
| 58 | + self.buttonCancel = Button(frameButtons, text='Cancel', |
| 59 | + width=8, command=self.Cancel) |
| 60 | + self.buttonCancel.pack(side=RIGHT, padx=5) |
| 61 | + |
| 62 | + def name_ok(self): |
| 63 | + ''' After stripping entered name, check that it is a sensible |
| 64 | + ConfigParser file section name. Return it if it is, '' if not. |
| 65 | + ''' |
| 66 | + name = self.name.get().strip() |
64 | 67 | if not name: #no name specified |
65 | 68 | tkMessageBox.showerror(title='Name Error', |
66 | 69 | message='No name specified.', parent=self) |
67 | | - nameOk=0 |
68 | 70 | elif len(name)>30: #name too long |
69 | 71 | tkMessageBox.showerror(title='Name Error', |
70 | 72 | message='Name too long. It should be no more than '+ |
71 | 73 | '30 characters.', parent=self) |
72 | | - nameOk=0 |
73 | | - elif name in self.usedNames: |
| 74 | + name = '' |
| 75 | + elif name in self.used_names: |
74 | 76 | tkMessageBox.showerror(title='Name Error', |
75 | 77 | message='This name is already in use.', parent=self) |
76 | | - nameOk=0 |
77 | | - return nameOk |
| 78 | + name = '' |
| 79 | + return name |
78 | 80 |
|
79 | 81 | def Ok(self, event=None): |
80 | | - if self.NameOk(): |
81 | | - self.result=self.name.get().strip() |
| 82 | + name = self.name_ok() |
| 83 | + if name: |
| 84 | + self.result = name |
82 | 85 | self.destroy() |
83 | 86 |
|
84 | 87 | def Cancel(self, event=None): |
85 | | - self.result='' |
| 88 | + self.result = '' |
86 | 89 | self.destroy() |
87 | 90 |
|
88 | 91 | if __name__ == '__main__': |
89 | | - #test the dialog |
90 | | - root=Tk() |
| 92 | + import unittest |
| 93 | + unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) |
| 94 | + |
| 95 | + # also human test the dialog |
| 96 | + root = Tk() |
91 | 97 | def run(): |
92 | | - keySeq='' |
93 | 98 | dlg=GetCfgSectionNameDialog(root,'Get Name', |
94 | | - 'The information here should need to be word wrapped. Test.') |
| 99 | + "After the text entered with [Ok] is stripped, <nothing>, " |
| 100 | + "'abc', or more that 30 chars are errors. " |
| 101 | + "Close with a valid entry (printed), [Cancel], or [X]", |
| 102 | + {'abc'}) |
95 | 103 | print(dlg.result) |
96 | | - Button(root,text='Dialog',command=run).pack() |
| 104 | + Message(root, text='').pack() # will be needed for oher dialog tests |
| 105 | + Button(root, text='Click to begin dialog test', command=run).pack() |
97 | 106 | root.mainloop() |
0 commit comments