Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / spread / ui / tkutil.py
1
2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 """Utilities for building L{PB<twisted.spread.pb>} clients with L{Tkinter}.
6 """
7 from Tkinter import *
8 from tkSimpleDialog import _QueryString
9 from tkFileDialog import _Dialog
10 from twisted.spread import pb
11 from twisted.internet import reactor
12 from twisted import copyright
13
14 import string
15
16 #normalFont = Font("-adobe-courier-medium-r-normal-*-*-120-*-*-m-*-iso8859-1")
17 #boldFont = Font("-adobe-courier-bold-r-normal-*-*-120-*-*-m-*-iso8859-1")
18 #errorFont = Font("-adobe-courier-medium-o-normal-*-*-120-*-*-m-*-iso8859-1")
19
20 class _QueryPassword(_QueryString):
21     def body(self, master):
22
23         w = Label(master, text=self.prompt, justify=LEFT)
24         w.grid(row=0, padx=5, sticky=W)
25
26         self.entry = Entry(master, name="entry",show="*")
27         self.entry.grid(row=1, padx=5, sticky=W+E)
28
29         if self.initialvalue:
30             self.entry.insert(0, self.initialvalue)
31             self.entry.select_range(0, END)
32
33         return self.entry
34
35 def askpassword(title, prompt, **kw):
36     '''get a password from the user
37
38     @param title: the dialog title
39     @param prompt: the label text
40     @param **kw: see L{SimpleDialog} class
41
42     @returns: a string
43     '''
44     d = apply(_QueryPassword, (title, prompt), kw)
45     return d.result
46
47 def grid_setexpand(widget):
48     cols,rows=widget.grid_size()
49     for i in range(cols):
50         widget.columnconfigure(i,weight=1)
51     for i in range(rows):
52         widget.rowconfigure(i,weight=1)
53
54 class CList(Frame):
55     def __init__(self,parent,labels,disablesorting=0,**kw):
56         Frame.__init__(self,parent)
57         self.labels=labels
58         self.lists=[]
59         self.disablesorting=disablesorting
60         kw["exportselection"]=0
61         for i in range(len(labels)):
62             b=Button(self,text=labels[i],anchor=W,height=1,pady=0)
63             b.config(command=lambda s=self,i=i:s.setSort(i))
64             b.grid(column=i,row=0,sticky=N+E+W)
65             box=apply(Listbox,(self,),kw)
66             box.grid(column=i,row=1,sticky=N+E+S+W)
67             self.lists.append(box)
68         grid_setexpand(self)
69         self.rowconfigure(0,weight=0)
70         self._callall("bind",'<Button-1>',self.Button1)
71         self._callall("bind",'<B1-Motion>',self.Button1)
72         self.bind('<Up>',self.UpKey)
73         self.bind('<Down>',self.DownKey)
74         self.sort=None
75
76     def _callall(self,funcname,*args,**kw):
77         rets=[]
78         for l in self.lists:
79             func=getattr(l,funcname)
80             ret=apply(func,args,kw)
81             if ret!=None: rets.append(ret)
82         if rets: return rets
83
84     def Button1(self,e):
85         index=self.nearest(e.y)
86         self.select_clear(0,END)
87         self.select_set(index)
88         self.activate(index)
89         return "break"
90
91     def UpKey(self,e):
92         index=self.index(ACTIVE)
93         if index:
94             self.select_clear(0,END)
95             self.select_set(index-1)
96         return "break"
97
98     def DownKey(self,e):
99         index=self.index(ACTIVE)
100         if index!=self.size()-1:
101             self.select_clear(0,END)
102             self.select_set(index+1)
103         return "break"
104
105     def setSort(self,index):
106         if self.sort==None:
107             self.sort=[index,1]
108         elif self.sort[0]==index:
109             self.sort[1]=-self.sort[1]
110         else:
111             self.sort=[index,1]
112         self._sort()
113
114     def _sort(self):
115         if self.disablesorting:
116             return
117         if self.sort==None:
118             return
119         ind,direc=self.sort
120         li=list(self.get(0,END))
121         li.sort(lambda x,y,i=ind,d=direc:d*cmp(x[i],y[i]))
122         self.delete(0,END)
123         for l in li:
124             self._insert(END,l)
125     def activate(self,index):
126         self._callall("activate",index)
127
128    # def bbox(self,index):
129    #     return self._callall("bbox",index)
130
131     def curselection(self):
132         return self.lists[0].curselection()
133
134     def delete(self,*args):
135         apply(self._callall,("delete",)+args)
136
137     def get(self,*args):
138         bad=apply(self._callall,("get",)+args)
139         if len(args)==1:
140             return bad
141         ret=[]
142         for i in range(len(bad[0])):
143             r=[]
144             for j in range(len(bad)):
145                 r.append(bad[j][i])
146             ret.append(r)
147         return ret
148
149     def index(self,index):
150         return self.lists[0].index(index)
151
152     def insert(self,index,items):
153         self._insert(index,items)
154         self._sort()
155
156     def _insert(self,index,items):
157         for i in range(len(items)):
158             self.lists[i].insert(index,items[i])
159
160     def nearest(self,y):
161         return self.lists[0].nearest(y)
162
163     def see(self,index):
164         self._callall("see",index)
165
166     def size(self):
167         return self.lists[0].size()
168
169     def selection_anchor(self,index):
170         self._callall("selection_anchor",index)
171
172     select_anchor=selection_anchor
173
174     def selection_clear(self,*args):
175         apply(self._callall,("selection_clear",)+args)
176
177     select_clear=selection_clear
178
179     def selection_includes(self,index):
180         return self.lists[0].select_includes(index)
181
182     select_includes=selection_includes
183
184     def selection_set(self,*args):
185         apply(self._callall,("selection_set",)+args)
186
187     select_set=selection_set
188
189     def xview(self,*args):
190         if not args: return self.lists[0].xview()
191         apply(self._callall,("xview",)+args)
192
193     def yview(self,*args):
194         if not args: return self.lists[0].yview()
195         apply(self._callall,("yview",)+args)
196
197 class ProgressBar:
198     def __init__(self, master=None, orientation="horizontal",
199                  min=0, max=100, width=100, height=18,
200                  doLabel=1, appearance="sunken",
201                  fillColor="blue", background="gray",
202                  labelColor="yellow", labelFont="Verdana",
203                  labelText="", labelFormat="%d%%",
204                  value=0, bd=2):
205         # preserve various values
206         self.master=master
207         self.orientation=orientation
208         self.min=min
209         self.max=max
210         self.width=width
211         self.height=height
212         self.doLabel=doLabel
213         self.fillColor=fillColor
214         self.labelFont= labelFont
215         self.labelColor=labelColor
216         self.background=background
217         self.labelText=labelText
218         self.labelFormat=labelFormat
219         self.value=value
220         self.frame=Frame(master, relief=appearance, bd=bd)
221         self.canvas=Canvas(self.frame, height=height, width=width, bd=0,
222                            highlightthickness=0, background=background)
223         self.scale=self.canvas.create_rectangle(0, 0, width, height,
224                                                 fill=fillColor)
225         self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
226                                            height / 2, text=labelText,
227                                            anchor="c", fill=labelColor,
228                                            font=self.labelFont)
229         self.update()
230         self.canvas.pack(side='top', fill='x', expand='no')
231
232     def updateProgress(self, newValue, newMax=None):
233         if newMax:
234             self.max = newMax
235         self.value = newValue
236         self.update()
237
238     def update(self):
239         # Trim the values to be between min and max
240         value=self.value
241         if value > self.max:
242             value = self.max
243         if value < self.min:
244             value = self.min
245         # Adjust the rectangle
246         if self.orientation == "horizontal":
247             self.canvas.coords(self.scale, 0, 0,
248               float(value) / self.max * self.width, self.height)
249         else:
250             self.canvas.coords(self.scale, 0,
251                                self.height - (float(value) /
252                                               self.max*self.height),
253                                self.width, self.height)
254         # Now update the colors
255         self.canvas.itemconfig(self.scale, fill=self.fillColor)
256         self.canvas.itemconfig(self.label, fill=self.labelColor)
257         # And update the label
258         if self.doLabel:
259             if value:
260                 if value >= 0:
261                     pvalue = int((float(value) / float(self.max)) *
262                                    100.0)
263                 else:
264                     pvalue = 0
265                 self.canvas.itemconfig(self.label, text=self.labelFormat
266                                          % pvalue)
267             else:
268                 self.canvas.itemconfig(self.label, text='')
269         else:
270             self.canvas.itemconfig(self.label, text=self.labelFormat %
271                                    self.labelText)
272         self.canvas.update_idletasks()
273
274 class DirectoryBrowser(_Dialog):
275     command = "tk_chooseDirectory"
276
277 def askdirectory(**options):
278     "Ask for a directory to save to."
279
280     return apply(DirectoryBrowser, (), options).show()
281
282 class GenericLogin(Toplevel):
283     def __init__(self,callback,buttons):
284         Toplevel.__init__(self)
285         self.callback=callback
286         Label(self,text="Twisted v%s"%copyright.version).grid(column=0,row=0,columnspan=2)
287         self.entries={}
288         row=1
289         for stuff in buttons:
290             label,value=stuff[:2]
291             if len(stuff)==3:
292                 dict=stuff[2]
293             else: dict={}
294             Label(self,text=label+": ").grid(column=0,row=row)
295             e=apply(Entry,(self,),dict)
296             e.grid(column=1,row=row)
297             e.insert(0,value)
298             self.entries[label]=e
299             row=row+1
300         Button(self,text="Login",command=self.doLogin).grid(column=0,row=row)
301         Button(self,text="Cancel",command=self.close).grid(column=1,row=row)
302         self.protocol('WM_DELETE_WINDOW',self.close)
303
304     def close(self):
305         self.tk.quit()
306         self.destroy()
307
308     def doLogin(self):
309         values={}
310         for k in self.entries.keys():
311             values[string.lower(k)]=self.entries[k].get()
312         self.callback(values)
313         self.destroy()
314
315 class Login(Toplevel):
316     def __init__(self,
317                  callback,
318                  referenced = None,
319                  initialUser = "guest",
320                  initialPassword = "guest",
321                  initialHostname = "localhost",
322                  initialService  = "",
323                  initialPortno   = pb.portno):
324         Toplevel.__init__(self)
325         version_label = Label(self,text="Twisted v%s" % copyright.version)
326         self.pbReferenceable = referenced
327         self.pbCallback = callback
328         # version_label.show()
329         self.username = Entry(self)
330         self.password = Entry(self,show='*')
331         self.hostname = Entry(self)
332         self.service  = Entry(self)
333         self.port     = Entry(self)
334
335         self.username.insert(0,initialUser)
336         self.password.insert(0,initialPassword)
337         self.service.insert(0,initialService)
338         self.hostname.insert(0,initialHostname)
339         self.port.insert(0,str(initialPortno))
340
341         userlbl=Label(self,text="Username:")
342         passlbl=Label(self,text="Password:")
343         servicelbl=Label(self,text="Service:")
344         hostlbl=Label(self,text="Hostname:")
345         portlbl=Label(self,text="Port #:")
346         self.logvar=StringVar()
347         self.logvar.set("Protocol PB-%s"%pb.Broker.version)
348         self.logstat  = Label(self,textvariable=self.logvar)
349         self.okbutton = Button(self,text="Log In", command=self.login)
350
351         version_label.grid(column=0,row=0,columnspan=2)
352         z=0
353         for i in [[userlbl,self.username],
354                   [passlbl,self.password],
355                   [hostlbl,self.hostname],
356                   [servicelbl,self.service],
357                   [portlbl,self.port]]:
358             i[0].grid(column=0,row=z+1)
359             i[1].grid(column=1,row=z+1)
360             z = z+1
361
362         self.logstat.grid(column=0,row=6,columnspan=2)
363         self.okbutton.grid(column=0,row=7,columnspan=2)
364
365         self.protocol('WM_DELETE_WINDOW',self.tk.quit)
366
367     def loginReset(self):
368         self.logvar.set("Idle.")
369
370     def loginReport(self, txt):
371         self.logvar.set(txt)
372         self.after(30000, self.loginReset)
373
374     def login(self):
375         host = self.hostname.get()
376         port = self.port.get()
377         service = self.service.get()
378         try:
379             port = int(port)
380         except:
381             pass
382         user = self.username.get()
383         pswd = self.password.get()
384         pb.connect(host, port, user, pswd, service,
385                    client=self.pbReferenceable).addCallback(self.pbCallback).addErrback(
386             self.couldNotConnect)
387
388     def couldNotConnect(self,f):
389         self.loginReport("could not connect:"+f.getErrorMessage())
390
391 if __name__=="__main__":
392     root=Tk()
393     o=CList(root,["Username","Online","Auto-Logon","Gateway"])
394     o.pack()
395     for i in range(0,16,4):
396         o.insert(END,[i,i+1,i+2,i+3])
397     mainloop()