Package Pmv :: Module guiTools
[hide private]
[frames] | no frames]

Source Code for Module Pmv.guiTools

  1  ############################################################################# 
  2  # 
  3  # Author: Sophie COON, Ruth HUEY, Michel F. SANNER 
  4  # 
  5  # Copyright: M. Sanner TSRI 2000 
  6  # 
  7  ############################################################################# 
  8   
  9   
 10  # 
 11  # $Header: /opt/cvs/python/packages/share1.5/Pmv/guiTools.py,v 1.13 2006/01/17 17:24:38 rhuey Exp $ 
 12  # 
 13  # $Id: guiTools.py,v 1.13 2006/01/17 17:24:38 rhuey Exp $ 
 14  # 
 15  """ 
 16  This Module implements useful tools for the MoleculeViewer: 
 17  for example: 
 18          MoleculeChooser 
 19  """ 
 20  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser, ObjectChooser 
 21  #from Framework.gui import ListChooser 
 22  import Tkinter 
 23  import Pmw 
 24  from MolKit.molecule import Molecule, MoleculeSet 
 25  from MolKit.tree import TreeNodeSet 
 26  from MolKit.protein import Protein, ProteinSet 
 27  ##  from ViewerFramework.gui import InputFormDescr 
 28  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
 29  import types 
 30   
31 -class MoleculeListChooser(ObjectChooser):
32 """class to present a list of molecules in a scrolled listbox.""" 33
34 - def __init__(self, root,mode='single', title='Choose', 35 molecules = None, cwcfg={'usehullsize':1, 36 'hull_width':100,'hull_height':80, 37 'text_wrap':'none'}, 38 lbpackcfg={'fill':'x', 'expand':1}, lbwcfg={}):
39 40 41 objects = self.buildObject(molecules) 42 ObjectChooser.__init__(self,root, mode, title, objects, cwcfg, 43 lbpackcfg,lbwcfg)
44 45 #self.entries = [] 46
47 - def buildObject(self, molecules):
48 objects = map(lambda x: (x, x.name, 49 x.parser.getMoleculeInformation()), 50 molecules) 51 return objects
52
53 - def add(self, molecule):
54 "Add an entry to the moleculelistchooser." 55 if not type(molecule)==types.TupleType: 56 object = self.buildEntry(molecule) 57 else: 58 object = molecule 59 ObjectChooser.add(self,object)
60
61 - def insert(self, pos, molecule):
62 object = self.buildObject(molecule) 63 ObjectChooser.insert(self,pos,object)
64
65 - def get(self, event = None):
66 if not self.lb.curselection(): 67 res = [] 68 else: 69 res = TreeNodeSet() 70 for ent in map( int, self.lb.curselection() ): 71 mol= self.nameObject[self.entries[ ent ][0]] 72 res.append(mol) 73 74 if self.mode=='single' and res: 75 res = res[0] 76 77 return res
78
79 -class MoleculeChooser:
80 """presents user w/ a list of molecules currently loaded; 81 mode can be 'single', 'browse', 'multiple' or 'extended'. 82 Molecules can be selected from the list or by picking in the camera. 83 84 OK button returns a list of entries which have been selected. 85 Cancel returns an empty list. 86 Typical usage is: 87 ans = MoleculeChooser(self.vf).go() 88 if ans !=[]: 89 then get the value(s) 90 NB: this class doesn't grab the focus and binds picking w/ 91 B1 to selecting the molecule in the MoleculeChooser. """ 92 93
94 - def __init__(self, viewer, mode = 'single', title = 'Choose Molecule'):
95 96 self.vf = viewer 97 self.mode = mode 98 self.ipf = InputFormDescr(title = title)
99 100
101 - def done_cb(self):
102 self.ap.stop() 103 self.ipf.form.destroy() 104 self.ipf.form = None
105
106 - def go(self, modal=1, blocking=0, event = "<ButtonRelease-1>"):
107 """Start the form""" 108 109 entries = [] 110 for i in range(len(self.vf.Mols)): 111 mol = self.vf.Mols[i] 112 molParser = mol.parser 113 molStr = molParser.getMoleculeInformation() 114 entries.append((mol.name, molStr)) 115 116 ## self.ipf.insert(0,{'name': 'Molecule', 117 ## 'widgetType': 'ListChooser', 118 ## 'title' : 'select a molecule', 119 ## 'mode' : self.mode, 120 ## 'entries' : entries}) 121 122 self.ipf.insert(0,{'name': 'Molecule', 123 'widgetType': ListChooser, 124 'wcfg':{ 125 'title' : 'select a molecule', 126 'mode' : self.mode, 127 'entries' : entries}, 128 'gridcfg':{'sticky':'wens'}}) 129 130 if not (modal or blocking): 131 self.ipf.append({'widgetType':Tkinter.Button, 132 'wcfg':{'text':'Dismiss', 133 'command': self.done_cb}, 134 'gridcfg':{'sticky':'we'}}) 135 136 from Pmv.picker import AtomPicker 137 self.ap = AtomPicker(self.vf, None, 0, callbacks=[self.onPick], 138 immediate=1) 139 self.ap.go(modal=0) 140 val = self.vf.getUserInput(self.ipf, modal=modal, blocking=blocking) 141 if val: 142 if modal or blocking: 143 if len(val['Molecule'])==1: 144 mols = self.vf.Mols.NodesFromName( val['Molecule'][0] ) 145 if self.mode=='single': return mols[0] 146 return mols 147 else: 148 molNames = "" 149 for m in val['Molecule']: 150 molNames = molNames+','+m 151 mols = self.vf.Mols.NodesFromName( molNames ) 152 self.ap.stop() 153 if self.mode=='single': return mols[0] 154 return mols 155 else: 156 self.form = val 157 return val 158 else: 159 return val
160
161 - def getMolSet(self):
162 """method to get currently selected molecules when the chooser is used 163 in modal=0 and blocking=0 mode""" 164 165 val = self.form.checkValues() 166 if len(val['Molecule'])==0: 167 t = "Nothing selected!" 168 self.vf.warningMsg(t, title="MoleculeChooser WARNING:") 169 return None 170 molNames = "" 171 for m in val['Molecule']: 172 # Create the list of names 173 if molNames == "": 174 molNames = m 175 else: 176 molNames = molNames + ";" + m 177 mols = self.vf.Mols.NodesFromName( molNames ) 178 if self.mode=='single': return mols[0] 179 return mols
180
181 - def onPick(self,atoms):
182 listChooser = self.ipf.entryByName['Molecule']['widget'] 183 tkListBox = listChooser.lb 184 if atoms: 185 pickedMol = atoms[0].top 186 #then need to make pickedMol the selection in self.lc 187 for i in range(len(listChooser.entries)): 188 if pickedMol.name == listChooser.entries[i][0]: 189 self.pickedMolIndex= i 190 tkListBox.select_clear(0,'end') 191 listChooser.select(i) 192 return 193 print "error: %s not in mv.Mols" %pickedMol.name
194 195
196 -class AugmentedMoleculeChooser(MoleculeChooser):
197 """presents user w/ a list of molecules currently loaded; 198 mode can be 'single', 'browse', 'multiple' or 'extended'. 199 Molecules can be selected from the list or by picking in the camera. 200 OK button returns a list of entries which have been selected. 201 Cancel returns an empty list. 202 Typical usage is: 203 ans = MoleculeChooser(self.vf).go() 204 if ans !=[]: 205 then get the value(s) 206 207 Extra dictionaries can be added to the inputform to obtain other user defined values. To do this, set extra to not None and extraDict to a list of dictionaries to be appended to the input form. 208 209 NB: this class doesn't grab the focus and binds picking w/ 210 B1 to selecting the molecule in the MoleculeChooser. """ 211 212
213 - def __init__(self, viewer, mode = 'single', title = 'Choose Molecule', selectTitle="select a molecule", extra=[], extraDict=None):
214 MoleculeChooser.__init__(self, viewer, mode, title) 215 self.extra = extra 216 self.extraDict = extraDict 217 self.selectTitle = selectTitle
218 219
220 - def go(self, modal=1, blocking=0, event = "<ButtonRelease-1>"):
221 """Start the form""" 222 223 entries = [] 224 for i in range(len(self.vf.Mols)): 225 mol = self.vf.Mols[i] 226 molParser = mol.parser 227 molStr = molParser.getMoleculeInformation() 228 entries.append((mol.name, molStr)) 229 230 self.ipf.insert(0,{'name': 'Molecule', 231 'widgetType': ListChooser, 232 'wcfg':{ 233 'title' : self.selectTitle, 234 'mode' : self.mode, 235 'entries' : entries}, 236 'gridcfg':{'sticky':'wens'}}) 237 238 for k in self.extra: 239 ct = 1 240 for d in self.extraDict: 241 self.ipf.insert(ct, d) 242 ct = ct + 1 243 244 if not (modal or blocking): 245 self.ipf.append({'widgetType':Tkinter.Button, 246 'wcfg':{'text':'Dismiss', 247 'command': self.done_cb}, 248 'gridcfg':{'sticky':'we'}}) 249 250 from Pmv.picker import AtomPicker 251 self.ap = AtomPicker(self.vf, None, 0, callbacks=[self.onPick], 252 immediate=1) 253 self.ap.go(modal=0) 254 val = self.vf.getUserInput(self.ipf, modal=modal, blocking=blocking) 255 if val: 256 if modal or blocking: 257 if len(val['Molecule'])==1: 258 mols = self.vf.Mols.NodesFromName( val['Molecule'][0] ) 259 if self.mode=='single': returnValue = mols[0] 260 #if self.mode=='single': return mols[0] 261 else: returnValue = mols 262 #return mols 263 else: 264 molNames = "" 265 for m in val['Molecule']: 266 molNames = molNames+','+m 267 mols = self.vf.Mols.NodesFromName( molNames ) 268 self.ap.stop() 269 #if self.mode=='single': return mols[0] 270 if self.mode=='single': returnValue = mols[0] 271 else: returnValue = mols 272 #return mols 273 #if self.extra is not None: 274 for k in self.extra: 275 returnValue = (returnValue, val[k]) 276 #returnValue = (returnValue, val[self.extra]) 277 return returnValue 278 279 else: 280 self.form = val 281 return val 282 else: 283 return val
284 285 # Tkinter interface to SYSV `ps' and `kill' commands. 286 287 from Tkinter import * 288 289 if TkVersion < 4.0: 290 raise ImportError, "This version of svkill requires Tk 4.0 or later" 291 292 from string import splitfields 293 from string import split 294 import commands 295 import sys,os 296 297 ## if sys.platform!='win32': 298 ## user = os.environ['LOGNAME'] 299 ## else: 300 ## user = 'NoName' 301 302 user = os.environ.get('LOGNAME', 'NoName') 303 304
305 -class BarButton(Menubutton):
306 - def __init__(self, master=None, **cnf):
307 apply(Menubutton.__init__, (self, master), cnf) 308 self.pack(side=LEFT) 309 self.menu = Menu(self, name='menu') 310 self['menu'] = self.menu
311
312 -class Kill(Frame):
313 # List of (name, option, pid_column) 314 view_list = [ 315 ('Default', ''), 316 ('Every (-e)', '-e'), 317 ('Non process group leaders (-d)', '-d'), 318 ('Non leaders with tty (-a)', '-a'), 319 ('For this user (-u %s)' % user, '-u %s' % user), 320 ] 321 format_list = [ 322 ('Default', '', 0), 323 ('Long (-l)', '-l', 3), 324 ('Full (-f)', '-f', 1), 325 ('Full Long (-f -l)', '-l -f', 3), 326 ('Session and group ID (-j)', '-j', 0), 327 ('Scheduler properties (-c)', '-c', 0), 328 ]
329 - def kill(self, selected):
330 c = self.format_list[self.format.get()][2] 331 pid = split(selected)[c] 332 os.system('kill -9 ' + pid) 333 self.do_update()
334 - def do_update(self):
335 format = self.format_list[self.format.get()][1] 336 view = self.view_list[self.view.get()][1] 337 s = commands.getoutput('ps %s %s' % (view, format)) 338 list = splitfields(s, '\n') 339 self.header.set(list[0] + ' ') 340 del list[0] 341 self.frame.list.delete(0, AtEnd()) 342 for line in list: 343 self.frame.list.insert(0, line)
344 - def do_motion(self, e):
345 e.widget.select_clear('0', 'end') 346 e.widget.select_set(e.widget.nearest(e.y))
347 - def do_leave(self, e):
348 e.widget.select_clear('0', 'end')
349 - def do_1(self, e):
350 self.kill(e.widget.get(e.widget.nearest(e.y)))
351 - def __init__(self, master=None, **cnf):
352 apply(Frame.__init__, (self, master), cnf) 353 self.pack(expand=1, fill=BOTH) 354 self.bar = Frame(self, name='bar', relief=RAISED, 355 borderwidth=2) 356 self.bar.pack(fill=X) 357 self.bar.file = BarButton(self.bar, text='File') 358 self.bar.file.menu.add_command( 359 label='Quit', command=self.quit) 360 self.bar.view = BarButton(self.bar, text='View') 361 self.bar.format = BarButton(self.bar, text='Format') 362 self.view = IntVar(self) 363 self.view.set(0) 364 self.format = IntVar(self) 365 self.format.set(0) 366 for num in range(len(self.view_list)): 367 label, option = self.view_list[num] 368 self.bar.view.menu.add_radiobutton( 369 label=label, 370 command=self.do_update, 371 variable=self.view, 372 value=num) 373 for num in range(len(self.format_list)): 374 label, option, col = self.format_list[num] 375 self.bar.format.menu.add_radiobutton( 376 label=label, 377 command=self.do_update, 378 variable=self.format, 379 value=num) 380 self.bar.tk_menuBar(self.bar.file, 381 self.bar.view, 382 self.bar.format) 383 self.frame = Frame(self, relief=RAISED, borderwidth=2) 384 self.frame.pack(expand=1, fill=BOTH) 385 self.header = StringVar(self) 386 self.frame.label = Label( 387 self.frame, relief=FLAT, anchor=NW, borderwidth=0, 388 font='*-Courier-Bold-R-Normal-*-120-*', 389 textvariable=self.header) 390 self.frame.label.pack(fill=Y, anchor=W) 391 self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) 392 self.frame.list = Listbox( 393 self.frame, 394 relief=SUNKEN, 395 font='*-Courier-Medium-R-Normal-*-120-*', 396 width=40, height=10, 397 selectbackground='#eed5b7', 398 selectborderwidth=0, 399 selectmode=BROWSE, 400 yscroll=self.frame.vscroll.set) 401 self.frame.vscroll['command'] = self.frame.list.yview 402 self.frame.vscroll.pack(side=RIGHT, fill=Y) 403 self.frame.list.pack(expand=1, fill=BOTH) 404 self.update = Button(self, text='Update', 405 command=self.do_update) 406 self.update.pack(fill=X) 407 self.frame.list.bind('<Motion>', self.do_motion) 408 self.frame.list.bind('<Leave>', self.do_leave) 409 self.frame.list.bind('<1>', self.do_1) 410 self.do_update()
411
412 -class CenterChooser:
413 """ 414 Class to allow a center to be defined (e.g. for the center of rotation 415 for a list of docking transformations). Returns either `Center on Molecule', 416 'Center on Selection', or a a list [x,y,z] specifying the center explicitly 417 """ 418
419 - def __init__(self,viewer):
420 self.ifd = InputFormDescr(title='Choose Center of Rotation') 421 self.vf = viewer
422 423
424 - def cancel_cb(self):
425 self.form.destroy()
426 427
428 - def go(self, modal= 1, blocking =0):
429 self.ifd.append({'widgetType':Pmw.RadioSelect, 430 'listtext':['Center on Molecule', 431 'Center on Selection', 432 'Type in Center'], 433 'defaultValue':'Type in Center', 434 'wcfg':{'orient':'vertical', 435 'buttontype':'radiobutton', 436 'command':self.setButton, 437 }}) 438 self.ifd.append({'widgetType':Pmw.EntryField, 439 'name':'X', 440 'validator':'real', 441 'wcfg':{'label_text':'X', 442 'labelpos':'w'}, 443 'gridcfg':{}}) 444 self.ifd.append({'widgetType':Pmw.EntryField, 445 'name':'Y', 446 'wcfg':{'label_text':'Y', 447 'labelpos':'w'}, 448 'gridcfg':{}}) 449 self.ifd.append({'widgetType':Pmw.EntryField, 450 'name':'Z', 451 'wcfg':{'label_text':'Z', 452 'labelpos':'w'}, 453 'gridcfg':{}}) 454 455 val = self.form = self.vf.getUserInput(self.ifd, modal=modal, 456 blocking=blocking) 457 if val: 458 if not (val['X'] and val['Y'] and val['Z']): 459 val = self.ifd[0]['widget'].selection 460 if val == 'Type in Center': 461 val = 'Center on Molecule' 462 print 'In CenterChooser: val =',val 463 return val 464 else: 465 val = [float(val['X']),float(val['Y']),float(val['Z'])] 466 return val
467 468
469 - def setButton(self,button):
470 x = self.ifd.entryByName['X'] 471 y = self.ifd.entryByName['Y'] 472 z = self.ifd.entryByName['Z'] 473 if button == 'Type in Center': 474 x['widget'].grid(x['gridcfg']) 475 y['widget'].grid(y['gridcfg']) 476 z['widget'].grid(z['gridcfg']) 477 else: 478 x['widget'].grid_forget() 479 y['widget'].grid_forget() 480 z['widget'].grid_forget()
481 482 483 if __name__ == '__main__': 484 kill = Kill(None, borderwidth=5) 485 kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') 486 kill.winfo_toplevel().minsize(1, 1) 487 kill.mainloop() 488