Package Vision :: Module nodeLibraries
[hide private]
[frames] | no frames]

Source Code for Module Vision.nodeLibraries

  1  ######################################################################## 
  2  # 
  3  # Date: Jul 2003  Authors: Daniel Stoffler, Michel Sanner 
  4  # 
  5  #       stoffler@scripps.edu 
  6  #       sanner@scripps.edu 
  7  # 
  8  #       The Scripps Research Institute (TSRI) 
  9  #       Molecular Graphics Lab 
 10  #       La Jolla, CA 92037, USA 
 11  # 
 12  # Copyright: Daniel Stoffler, Michel Sanner and TSRI 
 13  # 
 14  ######################################################################### 
 15   
 16  import os, sys 
 17  import re 
 18  import string 
 19  import types 
 20  import Tkinter, Pmw 
 21  from mglutil.gui.BasicWidgets.Tk.fileBrowsers import FileOpenBrowser 
 22  from mglutil.util.packageFilePath import findAllPackages, \ 
 23       findModulesInPackage, findModulesInDirectory 
 24  from mglutil.gui.BasicWidgets.Tk.colorWidgets import ColorChooser 
 25   
 26  # this file contains the node libraries that can be loaded into Vision 
 27  # the key is the name of the library, the value is a tuple with the first 
 28  # entry providing the path to the file and the second a list of required Python 
 29  # packages 
 30  libraries = { 
 31   'stdlib': ('Vision.StandardNodes',[])  
 32   } 
 33   
 34   
35 -class LoadLibraryPanel:
36 """A GUI to load Vision libraries. This object needs to be aware of the 37 Vision editor, which has to be passed to the constructor.""" 38
39 - def __init__(self, editor):
40 self.editor = editor # Vision editor 41 self.panel = None # this Tkinter panel 42 self.buildPanel() # build the panel 43 # pattern used to find the libname in the library file 44 self.pattern = re.compile('=NodeLibrary') 45 self.openFileBrowser = FileOpenBrowser() # File Browser widget
46 47
48 - def buildPanel(self):
49 # avoid rebuilding by potentially silly user... 50 if self.panel is not None: 51 self.show() 52 return 53 54 from Vision.nodeLibraries import libraries 55 libKeys = libraries.keys() 56 libKeys.sort() 57 58 root = self.panel = Tkinter.Toplevel() 59 root.title('Load Libraries') 60 root.protocol("WM_DELETE_WINDOW", self.hide) 61 frame = Tkinter.Frame(root) 62 frame.grid(columnspan=2) 63 64 # Scrolled widget 65 w = self.loadModuleWidget = Pmw.ScrolledListBox( 66 frame, 67 items=libKeys, 68 labelpos = 'n', 69 label_text = 'Select Library to be loaded', 70 dblclickcommand=self.loadLibs_cb) 71 w.grid(row=2, columnspan=2, padx=10, pady=10) 72 w.component('listbox').configure(selectmode=Tkinter.EXTENDED, 73 exportselection=0) 74 # widget balloon 75 balloon3 = Pmw.Balloon(frame) 76 balloon3.bind(w, 77 'Double-click entry, or choose multiple\nand hit OK') 78 79 b1 = Tkinter.Button(frame, text='OK',command=self.loadLibs_cb) 80 b1.grid(row=3,column=0,sticky='we') 81 82 b2 = Tkinter.Button(frame, text='Dismiss', command=self.hide) 83 b2.grid(row=3,column=1,sticky='we') 84 # bring to front 85 self.show()
86 87
88 - def loadLibrary(self, libname, libfile):
89 from Vision.nodeLibraries import libraries 90 libraries[libname] = (libfile, []) 91 self.editor.addLibraryFromName(libname)
92 93
94 - def loadLibs_cb(self, event=None):
95 # loading all the libraries currently selected in the widget 96 libnames = self.loadModuleWidget.getcurselection() 97 for libname in libnames: 98 self.editor.addLibraryFromName(libname)
99 100
101 - def show(self, event=None):
102 self.panel.deiconify()
103 104
105 - def hide(self, event=None):
106 self.panel.withdraw()
107 108
109 -class BrowseLibraryPanel:
110 """A GUI to browse for NodeLibraries in all available packages""" 111
112 - def __init__(self, editor):
113 self.editor = editor # Vision editor 114 self.panel = None # this Tkinter panel 115 self.mode = 'default' # can be 'default' or 'all' 116 self.buildPanel() # build the panel
117 118
119 - def buildPanel(self):
120 if self.panel is not None: 121 self.show() 122 return 123 124 root = self.panel = Tkinter.Toplevel() 125 root.title('Browse Vision Node Libraries') 126 root.protocol("WM_DELETE_WINDOW", self.hide) 127 frame = Tkinter.Frame(root) 128 frame.grid(columnspan=3) 129 130 #self.packages = findAllPackages() 131 #packNames = self.packages.keys() 132 #packNames.sort() 133 134 self.findDefaultPackages() 135 packNames = self.packages.keys() 136 packNames.sort() 137 138 rownum = 0 139 # browse button 140 browseLab = Tkinter.Label(frame, text='Directory of File: ') 141 browseLab.grid(row=rownum, column=0, sticky='e') 142 self.fileOrDirTkVar = Tkinter.StringVar() 143 browseEntry = Tkinter.Entry(frame, textvariable=self.fileOrDirTkVar) 144 browseEntry.grid(row=rownum, column=1, columnspan=2, sticky='ew') 145 browseEntry.bind('<Double-1>', self.fileBrowser_cb) 146 browseEntry.bind('<Return>', self.open_cb) 147 148 rownum+=1 149 # Scrolled widget showing all available packages 150 self.packageGUI = Pmw.ScrolledListBox( 151 frame, 152 hscrollmode='static', 153 items=packNames, 154 labelpos = 'n', 155 label_text = 'Select Package:', 156 #dblclickcommand=self.browsePackage_cb, 157 selectioncommand=self.browsePackage_cb, 158 listbox_exportselection=0) 159 self.packageGUI.component('horizscrollbar').configure(width=10) 160 self.packageGUI.component('vertscrollbar').configure(width=10) 161 162 self.packageGUI.grid(row=rownum, column=0, padx=10, pady=10) 163 164 # Scrolled widget showing all modules with potential NodeLibraries 165 self.moduleGUI = Pmw.ScrolledListBox( 166 frame, 167 hscrollmode='static', 168 items='', 169 labelpos = 'n', 170 label_text = 'Select Module:', 171 #dblclickcommand=self.browseLibs_cb, 172 selectioncommand=self.browseLibs_cb, 173 listbox_exportselection=0) 174 self.moduleGUI.grid(row=rownum, column=1, padx=10, pady=10) 175 self.moduleGUI.component('horizscrollbar').configure(width=10) 176 177 # Scrolled widget showing all NodeLibraries in a given module 178 self.libraryGUI = Pmw.ScrolledListBox( 179 frame, 180 hscrollmode='static', 181 items='', 182 labelpos = 'n', 183 label_text = 'Select Library:', 184 dblclickcommand=self.loadLib_cb, 185 #selectioncommand=self.loadLib_cb, 186 listbox_exportselection=0) 187 self.libraryGUI.grid(row=rownum, column=2, padx=10, pady=10) 188 self.libraryGUI.component('horizscrollbar').configure(width=10) 189 rownum+=1 190 191 ## reload = Tkinter.Button(frame, text='Reload Packages', 192 ## command=self.reloadPackages_cb) 193 ## reload.grid(row=rownum, column=0, sticky='we') 194 195 load = Tkinter.Button(frame, text='Load Library', 196 command=self.loadLib_cb) 197 load.grid(row=rownum, column=2, sticky='we') 198 199 ## rownum+=1 200 201 self.modeButton = Tkinter.Button(frame, text='Show All', 202 command=self.switchButton_cb) 203 self.modeButton.grid(row=rownum, column=0, sticky='we') 204 205 rownum+=1 206 dismiss = Tkinter.Button(frame, text='Dismiss', command=self.hide) 207 dismiss.grid(row=rownum, columnspan=3, sticky='we')
208 209
210 - def open_cb(self, event=None):
211 name = self.fileOrDirTkVar.get() 212 from os import path 213 if path.isdir(name): 214 from glob import glob 215 self.moduleGUI.component('listbox').delete(0,'end') 216 mods = glob(path.join(name, '*.PY')) 217 mods.sort() 218 self.modules = findModulesInDirectory(name, 'NodeLibrary') 219 modNames = [] 220 for key, value in self.modules.items(): 221 pathPack = key.split(os.path.sep) 222 if pathPack[-1] == packName: 223 newModName = map(lambda x: x[:-3], value) 224 modNames = modNames + newModName 225 else: 226 pIndex = pathPack.index(packName) 227 prefix = string.join(pathPack[pIndex+1:], '.') 228 newModName = map(lambda x: "%s.%s"%(prefix, x[:-3]), value) 229 modNames = modNames + newModName 230 modNames.sort() 231 self.moduleGUI.setlist(modNames) 232 233 elif path.isfile(name): 234 import sys 235 direct, file = path.split(name) 236 sys.path.insert(0, direct) 237 mod = __import__(file) 238 self.libs = self.getLibraries(mod) 239 sys.path = sys.path[1:]
240 241
242 - def fileBrowser_cb(self, event=None):
243 from tkFileDialog import asksaveasfilename 244 from tkFileDialog import askopenfilename 245 #file = asksaveasfilename( 246 file = askopenfilename( 247 filetypes=[ ('python', '*.py'), ('All files', '*')], 248 # initialdir=self.currentdir, initialfile=libName+'.py', 249 title='Open library file') 250 251 if file=='': 252 return 253 else: 254 self.fileOrDirTkVar.set(file) 255 self.open_cb()
256 257
258 - def getLibraries(self, mod):
259 from Vision.VPE import NodeLibrary 260 libs = {} 261 262 filename = mod.__file__ 263 if filename[-1] in ["c","o"]: # slice c from pyc or o from pyo 264 filename = filename[:-1] 265 f = open(filename) 266 sourceCode = f.read() 267 f.close() 268 269 for name in dir(mod): 270 obj = getattr(mod, name) 271 if isinstance(obj, NodeLibrary): 272 # only add libraries that are actually created in this file 273 patt = re.compile(".*%s *= *NodeLibrary"%name) 274 found = patt.search(sourceCode) 275 if found: 276 obj.modName = name 277 libs[obj.name] = obj 278 else: 279 patt = re.compile("locals *\( *\) *\[ *libInstanceName *\] *= *NodeLibrary") 280 found = patt.search(sourceCode) 281 if found: 282 obj.modName = name 283 libs[obj.name] = obj 284 285 libNames = libs.keys() 286 libNames.sort() 287 self.libraryGUI.setlist(libNames) 288 return libs
289 290
291 - def getModules(self, package):
292 self.modules = findModulesInPackage(package, 'NodeLibrary') 293 packName = self.packageGUI.getcurselection()[0] 294 modNames = [] 295 for key, value in self.modules.items(): 296 pathPack = key.split(os.path.sep) 297 if pathPack[-1] == packName: 298 newModName = map(lambda x: x[:-3], value) 299 modNames = modNames + newModName 300 else: 301 pIndex = pathPack.index(packName) 302 prefix = string.join(pathPack[pIndex+1:], '.') 303 newModName = map(lambda x: "%s.%s"%(prefix, x[:-3]), value) 304 modNames = modNames + newModName 305 modNames.sort() 306 self.moduleGUI.setlist(modNames) 307 self.libraryGUI.clear()
308
309 - def browsePackage_cb(self, event=None):
310 sel = self.packageGUI.getcurselection() 311 if len(sel) == 0: 312 return 313 packName = sel[0] 314 package = self.packages[packName] 315 self.getModules(package)
316 317
318 - def browseLibs_cb(self, event=None):
319 if len(self.moduleGUI.getcurselection()) == 0: 320 return 321 modName = self.moduleGUI.getcurselection()[0] 322 packName = self.packageGUI.getcurselection()[0] 323 importName = modName.replace(".", os.path.sep) 324 #pathName = "%s%s%s.py"%(packName,os.path.sep,importName) 325 #dir, file = os.path.split(pathName) 326 #sys.path.insert(0, dir) 327 mod = __import__(packName+'.'+modName, globals(), locals(), 328 [modName.split('.')[-1]]) 329 #sys.path = sys.path[1:] 330 self.libs = self.getLibraries(mod)
331 332
333 - def loadLib_cb(self, event=None):
334 try: 335 libName = self.libraryGUI.getcurselection()[0] 336 except: 337 return 338 lib = self.libs[libName] 339 packName = self.packageGUI.getcurselection()[0] 340 modName = self.moduleGUI.getcurselection()[0] 341 self.editor.addLibraryInstance(lib, packName+'.'+modName, lib.modName)
342 343
344 - def show(self, event=None):
345 self.panel.deiconify()
346 347
348 - def hide(self, event=None):
349 self.panel.withdraw()
350 351
352 - def reloadPackages_cb(self, event=None):
353 self.packages = findAllPackages() 354 packNames = self.packages.keys() 355 packNames.sort() 356 self.packageGUI.setlist(packNames) 357 self.moduleGUI.clear() 358 self.libraryGUI.clear()
359 360
361 - def showDefaultPackages_cb(self, event=None):
362 self.findDefaultPackages() 363 packNames = self.packages.keys() 364 packNames.sort() 365 self.packageGUI.setlist(packNames) 366 self.moduleGUI.clear() 367 self.libraryGUI.clear()
368 369
370 - def showAllPackages_cb(self, event=None):
371 self.reloadPackages_cb()
372 373
374 - def switchButton_cb(self, event=None):
375 if self.mode == 'default': 376 self.reloadPackages_cb() 377 self.mode = 'all' 378 self.modeButton.configure(text='Show Default') 379 else: 380 self.showDefaultPackages_cb() 381 self.mode = 'default' 382 self.modeButton.configure(text='Show All')
383 384
385 - def findDefaultPackages(self):
386 packages = findAllPackages() 387 default = [ 388 'ARTK', 'DejaVu', 'FlexTree', 'MolKit', 'Pmv', 'Vision', 389 'Volume', 'symserv'] 390 391 # do these default values exist? 392 tmp = [] 393 for k in default: 394 if k in packages.keys(): 395 tmp.append(k) 396 default = tmp 397 398 # now build the default list 399 for k in packages.keys(): 400 if k not in default: 401 del packages[k] 402 self.packages = packages
403 404
405 -class CreateLibraryPanel:
406 """A GUI to create a new library of nodes""" 407
408 - def __init__(self, editor):
409 self.editor = editor # Vision editor 410 self.panel = None # this Tkinter panel 411 self.buildPanel() # build the panel
412 413
414 - def buildPanel(self):
415 if self.panel is not None: 416 self.show() 417 return 418 419 root = self.panel = Tkinter.Toplevel() 420 root.title('Create Node Library') 421 root.protocol("WM_DELETE_WINDOW", self.hide) 422 frame = Tkinter.Frame(root) 423 frame.pack(expand=1, fill='both') 424 425 rownum=0 426 self.libclassnametkvar = Tkinter.StringVar() 427 Tkinter.Label(frame, text='Library class name:').grid( 428 row=rownum, column=0,sticky='e') 429 self.libclassnametk = Tkinter.Entry( 430 frame, textvariable=self.libclassnametkvar) 431 self.libclassnametk.grid(row=rownum, column=1, sticky='w') 432 rownum += 1 433 434 self.libnametkvar = Tkinter.StringVar() 435 Tkinter.Label(frame, text='Library name:').grid(row=rownum, column=0, 436 sticky='e') 437 self.libnametk = Tkinter.Entry(frame, textvariable=self.libnametkvar) 438 self.libnametk.grid(row=rownum, column=1, sticky='w') 439 rownum += 1 440 441 self.libfiletkvar = Tkinter.StringVar() 442 Tkinter.Label(frame, text='Library file:').grid(row=rownum, column=0, 443 sticky='e') 444 self.libfiletk = Tkinter.Entry(frame, textvariable=self.libfiletkvar) 445 self.libfiletk.grid(row=rownum, column=1, sticky='w') 446 rownum += 1 447 448 libDirs = [] 449 for directory in self.editor.userLibsDirs.keys(): 450 libDirs.append(directory) 451 452 self.libsGUI = Pmw.ScrolledListBox(frame, items=libDirs, 453 labelpos = 'n', 454 label_text = 'Select library directory:', 455 dblclickcommand=None) 456 self.libsGUI.grid(row=rownum, columnspan=2, padx=1, pady=1) 457 458 rownum += 1 459 460 self.colorButton = Tkinter.Button(frame, text='Library Color ...', 461 command=self.chooseColor) 462 self.colorButton.grid(row=rownum, column=0, columnspan=2, sticky='ew') 463 rownum += 1 464 465 createButton = Tkinter.Button(frame, text='Create', 466 command=self.createLib_cb) 467 createButton.grid(row=rownum, column=0, sticky='we') 468 469 dismiss = Tkinter.Button(frame, text='Dismiss', command=self.hide) 470 dismiss.grid(row=rownum, column=1, sticky='we')
471 472
473 - def chooseColor(self, event=None):
474 top = Tkinter.Toplevel() 475 colorChooser = ColorChooser(top, title='library color', immediate=1, 476 commands=[self.setColor]) 477 colorChooser.pack()
478 479
480 - def setColor(self, color):
481 from mglutil.util.colorUtil import ToHEX 482 self.colorButton.configure(bg=ToHEX(color))
483 484
485 - def createLib_cb(self, event=None):
486 classname = self.libclassnametkvar.get() 487 if classname is None or len(classname)==0: 488 return 489 490 name = self.libnametkvar.get() 491 if name is None or len(name)==0: 492 return 493 494 495 libfilename = self.libfiletkvar.get() 496 if libfilename is None or len(libfilename) == 0: 497 return 498 499 if libfilename[-3:] != ".py": 500 libfilename = libfilename + ".py" 501 502 directory = self.libsGUI.get() 503 if directory is None or len(directory)==0 or directory==(): 504 return 505 506 # libsGUI might return the data packed in a tuple 507 if type(directory) == types.TupleType: 508 directory = directory[0] 509 510 # build path by joining the directory with the parent path 511 path = os.path.join(self.editor.userLibsDirs[directory], directory) 512 513 # then add the file name 514 file = os.path.join(path, libfilename) 515 516 if os.path.exists(file): 517 from Dialog import Dialog 518 d = Dialog(None, {'title': 'File exisits', 519 'text': 520 'File "%s" already exists.' 521 ' Do you want to overwrite it ?'%file, 522 'bitmap': 'warning', 523 'default': 1, 524 'strings': ('Yes', 525 'No')}) 526 if d.num==1: # 'No' 527 return 528 529 from Vision.VPE import NodeLibrary 530 col = self.colorButton.cget('bg') 531 newlib = NodeLibrary(name, col, mode='readWrite') 532 newlib.varName = classname 533 534 # write the library header 535 f = open(file, 'w') 536 map( f.write, newlib.getHeader()) 537 f.write("%s = NodeLibrary('%s', '%s', mode='readWrite')\n"%( 538 newlib.varName, name, col)) 539 540 f.close() 541 542 # load the library from the file using same mechanism as saved network 543 from mglutil.util.packageFilePath import getObjectFromFile 544 newlib = getObjectFromFile( file, classname) 545 newlib.varName = classname 546 547 modName = directory + "." + libfilename[:-3] 548 modName = string.replace(modName, "/", ".") 549 newlib.modName = modName 550 # we need to __import__ to add this module to sys.modules 551 # This fixes a problem when trying to add nodes to this new lib before 552 # we restart and load the new library through 'loadLibrary' 553 __import__(modName) 554 555 self.editor.libraries[ newlib.name] = newlib 556 self.editor.showLibrary(newlib) 557 self.hide()
558 559
560 - def show(self, event=None):
561 self.panel.deiconify()
562 563
564 - def hide(self, event=None):
565 self.panel.withdraw()
566 567
568 -class AddNodeToUserLibraryPanel:
569 """A GUI to add a node to a user-defined node library""" 570
571 - def __init__(self, editor):
572 self.editor = editor # Vision editor 573 self.panel = None # this Tkinter panel 574 self.buildPanel() # build the panel 575 self.currentdir = os.getcwd() # memory of directory used to save
576 577
578 - def buildPanel(self):
579 if self.panel is not None: 580 self.show() 581 return 582 583 root = self.panel = Tkinter.Toplevel() 584 root.title('Add Node To User Library') 585 self.frame = Tkinter.Frame(root) 586 587 # find all readWrite libraries 588 libs = [] 589 for libname, lib in self.editor.libraries.items(): 590 if lib.mode == 'readWrite': 591 libs.append(libname) 592 libs.sort() 593 594 row = 0 595 596 self.label1 = Tkinter.Label(self.frame, text='Node class name: ') 597 self.label1.grid(row=row, column=0, sticky='w') 598 599 self.classNameTk = Tkinter.StringVar() 600 self.classNameEntry = Tkinter.Entry(self.frame, 601 textvariable= self.classNameTk) 602 self.classNameEntry.grid(row=row, column=1, sticky='ew') 603 604 row += 1 605 606 self.label2 = Tkinter.Label(self.frame, text='Library Category: ') 607 self.label2.grid(row=row, column=0, sticky='w') 608 609 self.categoryNameTk = Tkinter.StringVar() 610 self.categoryNameEntry = Tkinter.Entry(self.frame, 611 textvariable= self.categoryNameTk) 612 self.categoryNameEntry.grid(row=row, column=1, sticky='ew') 613 614 row += 1 615 616 # Scrolled widget showing all available readWrite libraries 617 self.libsGUI = Pmw.ScrolledListBox( 618 self.frame, items=libs, labelpos = 'n', 619 label_text = 'Select library to add node', 620 dblclickcommand=None) 621 self.libsGUI.grid(row=row, column=0, columnspan=2, padx=10, pady=10) 622 623 row += 1 624 625 self.save = Tkinter.Button(self.frame, text='Add Node...', 626 command=self.addNode_cb) 627 self.save.grid(row=row, column=0, sticky='we') 628 629 self.cancel = Tkinter.Button(self.frame, text='Dismiss', 630 command=self.hide) 631 self.cancel.grid(row=row, column=1, sticky='we') 632 self.frame.grid(columnspan=3, sticky='ew')
633 634
635 - def addNode_cb(self, event=None):
636 classname = self.classNameTk.get() 637 if classname is None or len(classname) == 0: 638 return 639 640 category = self.categoryNameTk.get() 641 if category is None or len(category) == 0: 642 return 643 644 libname = self.libsGUI.get() 645 if libname is None or len(libname) == 0 or libname == (): 646 return 647 libname = libname[0] 648 library = self.editor.libraries[libname] 649 650 if len(self.editor.currentNetwork.selectedNodes) != 1: 651 return 652 node = self.editor.currentNetwork.selectedNodes[0] 653 654 self.editor.addNodeToUserLibrary(node, classname, category, library) 655 self.hide()
656 657
658 - def show(self, event=None):
659 self.panel.deiconify() 660 661 # find all readWrite libraries 662 libs = [] 663 for libname, lib in self.editor.libraries.items(): 664 if lib.mode == 'readWrite': 665 libs.append(libname) 666 libs.sort() 667 self.libsGUI.setlist(libs)
668 669 670 671
672 - def hide(self, event=None):
673 self.panel.withdraw()
674